Emacs 是当今最强大的文本编辑器。与大多数其他编辑器不同(特别是与标准 Unix 编辑器 vi不同),Emacs 是一个完整的工作环境。无论你做什么,你都可以早上启动 Emacs,日以继夜地工作,再也不会离开它:你可以用它来编辑、重命名、删除和整理文件;编译程序;运行 shell 命令;等等。在 X 和 Microsoft Windows 等窗口系统流行之前,Emacs 通常充当自己的完整窗口系统。您所需要的只是一个终端,您就可以永远生活在 Emacs 中。 Emacs 还具有无限的灵活性;您可以编写自己的命令,更改与命令关联的键,并且(如果您愿意花时间)做任何您想做的事情。
Emacs is the most powerful text editor available today. Unlike most other editors (in particular, unlike the standard Unix editor, vi), Emacs is a complete working environment. No matter what you do, you can start Emacs in the morning, work all day and all night, and never leave it: you can use it to edit, rename, delete, and organize files; to compile programs; to run shell commands; and so on. Before windowing systems like X and Microsoft Windows became popular, Emacs often served as a complete windowing system of its own. All you needed was a terminal, and you could live within Emacs forever. Emacs is also infinitely flexible; you can write your own commands, change the keys that are associated with commands, and (if you are willing to take the time) do just about anything you want.
由于 Emacs 的功能非常多,因此它被认为极其复杂。我们认为这是没有道理的;我们从头开始教您 Emacs,首先介绍基础知识,然后介绍一些更高级的功能。
Because it does so much, Emacs has a reputation for being extremely complicated. We don't think that's warranted; we teach you Emacs from the ground up, covering first the basics and then some of the more advanced features.
在本书中,我们试图覆盖尽可能广泛的读者:从临时用户到专业作家、网络作者、程序员到系统管理员。无论您使用 Emacs 做什么,您都会发现它很容易学习;经过一两次课程后,您将了解编辑任何文件的基础知识。学习基础知识后,您可以继续学习更高级的主题,这些主题提供了使用 Emacs 的真正好处。这些包括:
In this book, we have tried to reach as broad an audience as possible: from casual users to professional writers and web authors to programmers to system administrators. No matter what you do with Emacs, you will find it's easy to learn; after one or two sessions, you'll know the basics of editing any file. After you learn the basics, you can go on to learn about more advanced topics that provide the real benefits of using Emacs. These include:
使用多个窗口和缓冲区,以便您可以同时处理多个文件
Using multiple windows and buffers so you can work on several files at once
自定义键盘命令
Customizing keyboard commands
定制 Emacs 以适合您的工作风格
Tailoring Emacs to fit your work style
让 Emacs 成为您的工作环境,您可以在其中执行所有日常任务,例如组织文件、编译程序和发出 shell 命令
Making Emacs your work environment where you can do all your everyday tasks, such as organizing files, compiling programs, and issuing shell commands
创建宏以简化重复性任务
Creating macros to streamline repetitive tasks
使用 Emacs 支持多种语言编程(包括 C、C++、Lisp、Java 和 Perl)
Using Emacs to support programming in many languages (including C, C++, Lisp, Java, and Perl)
使用各种标记语言(例如 HTML 和 XML)格式化文件
Formatting files with various markup languages, such as HTML and XML
使用单词缩写来避免拼写出长短语或纠正常见的拼写错误
Using word abbreviations to avoid spelling out long phrases or to correct common misspellings
当然,许多主题可能不适用于您;有些主题可能适合第二遍阅读,但不适合第一次阅读。在序言的最后,我们将根据您的兴趣和经验概述几种不同的阅读本书的方法。
Of course, many of the topics may not apply to you; some topics may be appropriate for a second reading but not for the first. Toward the end of the preface, we'll sketch several different ways to approach the book, depending on your interests and experience.
Emacs 有许多版本,提供了广泛的功能,但目前广泛使用的有两个版本:GNU Emacs 和 XEmacs。 (Emacs 实现的详尽列表可以在 http://www.finseth.com/~fin/emacs.html找到。)XEmacs 最初是为 GUI 使用而定制的,拥有相当广泛的用户群,但缺乏一些功能GNU Emacs 的。[ 1 ]
Numerous versions of Emacs are available, offering a wide range of features, but two are in widespread use today: GNU Emacs and XEmacs. (An exhaustive list of Emacs implementations can be found at http://www.finseth.com/~fin/emacs.html.) XEmacs was originally tailored for GUI usage and has a fairly wide user base, but lacks some of the features of GNU Emacs.[1]
本书涵盖了 GNU Emacs。自从出现以来,GNU Emacs 已经成为最流行、最强大、最灵活的 Emacs,并且没有理由相信这种情况会改变。如果您了解 GNU Emacs,您将能够毫无困难地适应任何其他 Emacs 实现;走向另一个方向并不那么容易。
This book covers GNU Emacs. Since its appearance, GNU Emacs has become the most popular, powerful, and flexible Emacs, and there's no reason to believe that this situation will change. If you know GNU Emacs, you will be able to adapt to any other Emacs implementation with no trouble; it's not so easy to go in the other direction.
然而,本书并不局限于 GNU Emacs 用户。由于不同 Emacs 实现之间的相似性,本书应该可以帮助您开始使用任何 Emacs 编辑器。基本的键盘命令从一个编辑器到另一个编辑器几乎没有变化 - 您会发现Cn(代表Ctrl-n)几乎总是意味着“移至下一行”。 Emacs 编辑器往往在更高级的命令和功能方面有所不同,但如果您正在使用这些更高级的工具并且不使用 GNU Emacs,则应该考虑进行切换。
This book, however, isn't limited to GNU Emacs users. Because of the similarities between different Emacs implementations, this book should help you get started with any Emacs editor. The basic keyboard commands change little from one editor to another—you'll find that C-n (for Ctrl-n) almost always means "move to the next line." Emacs editors tend to differ in the more advanced commands and features, but if you are using these more advanced facilities and you aren't using GNU Emacs, you should consider making the switch.
[ 1 ]在 GNU Emacs 与 XEmacs 的讨论中出现了相当多的问题,其中包括字符编码方案、用户界面差异和版权问题。我们对在这些 emacsen 之间的战斗中选边站没有兴趣。
[1] Quite a few issues come up in discussions of GNU Emacs versus XEmacs, with character encoding schemes, user interface differences, and copyright issues among them. We're not interested in taking sides in the battles between these emacsen.
第三版涵盖了 GNU Emacs 21,特别是 21.3,更具体地说是 21.3.5。[ 2 ]这个新版本已经过全面修订和扩展,以涵盖新功能并满足 Emacs 用户不断变化的需求。
This third edition covers GNU Emacs 21, specifically 21.3 and even more specifically 21.3.5.[2] This new edition has been completely revised and expanded to cover new features and to meet the evolving needs of Emacs users.
以下是我们所做更改的一些亮点:
Here are some of the highlights of what we've changed:
用户界面更改,包括添加基于图标的工具栏、对菜单进行大量更改以及更加图形化的界面(第 1 章)
User interface changes, including the addition of an icon-based toolbar, extensive changes to menus, and a more graphical interface (Chapter 1)
Emacs 如何与操作系统剪贴板交互,包括具体的剪贴板相关命令(第 2 章)
How Emacs interacts with the operating system clipboard, including specific clipboard-related commands (Chapter 2)
动态缩写(第三章)
Dynamic abbreviations (Chapter 3)
扩展了目录编辑器 Dired 的覆盖范围,可帮助您更有效地组织和处理文件(第 5 章)
Expanded coverage of the directory editor, Dired, to help you organize and work with files more efficiently (Chapter 5)
更改 Emacs 处理制表符和缩进的方式以及如何让 Emacs 执行您想要的操作(第 7 章)
Changes to the way Emacs handles tabs and indentation and how to get Emacs to do what you want it to (Chapter 7)
用鼠标绘图的艺术家模式(第 7 章)
Artist mode for drawing with the mouse (Chapter 7)
在 HTML 文件中插入其他字符集的字符(第 8 章)
Inserting characters from other character sets in HTML files (Chapter 8)
使用字体锁定模式为文本着色以便于编辑(第 9 章)
Using font-lock mode for coloring text for easier editing (Chapter 9)
扩展了 Java 覆盖范围,包括如何安装和使用 Emacs Java 开发环境 (JDEE)(第 9 章)
Expanded Java coverage, including how to install and use the Java Development Environment for Emacs (JDEE) (Chapter 9)
Cperl 模式下的 Perl 支持(第 9 章)
Perl support with Cperl mode (Chapter 9)
使用 etag 更有效地管理大型多文件项目的更改(第 9 章)
Managing changes to large, multiple file projects more effectively using etags (Chapter 9)
通过交互式自定义界面或通过.emacs启动文件自定义 Emacs(第 10 章)
Customizing Emacs through the interactive Custom interface or through the .emacs startup file (Chapter 10)
扩展了版本控制模式如何与各种变更控制系统连接的内容,包括 CVS、RCS、Subversion 和 SCCS(第 12 章)
Expanded coverage of how version control mode connects with a variety of change control systems, including CVS, RCS, Subversion, and SCCS (Chapter 12)
关于特定于平台的注意事项的新章节,包括如何在 Unix、Windows 和 Mac OS X 上安装最新版本的 Emacs 的详细信息(第 13 章)
A new chapter on platform-specific considerations, including details on how to install the latest version of Emacs on Unix, Windows, and Mac OS X (Chapter 13)
您无需了解它的历史即可使用 GNU Emacs,但它的起源是计算机历史中一个有趣的部分。维护和分发 GNU Emacs 的自由软件基金会 (FSF) 已成为计算机文化的重要组成部分。
You don't need to know its history to use GNU Emacs, but its origins are an interesting part of computer history. The Free Software Foundation (FSF), which maintains and distributes GNU Emacs, has become an important part of computer culture.
很久以前(1975 年),Richard Stallman 在麻省理工学院编写了第一个 Emacs 编辑器。根据民间传说,最初的 Emacs 编辑器是 TECO 的一组宏,TECO 是一种几乎难以理解且现已过时的行编辑器。 Emacs 这个名字代表“编辑宏”。传统上还认为,Emacs 是根据一家最喜欢的冰淇淋店的名字来命名的。自 1975 年以来发生了很多事情。TECO 已经陷入了应有的默默无闻,Emacs 也被重写为一个独立的程序。 Emacs 出现了几个商业版本,其中最重要的是 Unipress Emacs 和 CCA Emacs。多年来,这些商业实现是您在学术界之外最有可能遇到的 Emacs 编辑器。
A long time ago (1975) at MIT, Richard Stallman wrote the first Emacs editor. According to the folklore, the original Emacs editor was a set of macros for TECO, an almost incomprehensible and now obsolete line editor. The name Emacs stands for "Editing Macros." Tradition also has it that Emacs is a play on the name of a favorite ice cream store. Much has happened since 1975. TECO has slipped into deserved obscurity, and Emacs has been rewritten as an independent program. Several commercial versions of Emacs appeared, of which Unipress Emacs and CCA Emacs were the most important. For several years, these commercial implementations were the Emacs editors you were most likely to run across outside of the academic world.
Stallman 的 Emacs 随着 1984 年自由软件基金会 (FSF) 和 GNU 项目的诞生而声名鹊起。GNU 代表“GNU's Not Unix”,指的是 Stallman 和他的同事正在构建的一个完整的类 Unix 操作系统 (OS) 。
Stallman's Emacs became prominent with the birth of the Free Software Foundation (FSF) and the GNU Project in 1984. GNU stands for "GNU's Not Unix" and refers to a complete Unix-like operating system (OS) that Stallman and his associates were building.
斯托曼创立 FSF 是为了保证某些软件始终保持免费。请注意,免费并不一定意味着便宜(您可能需要支付一定的费用来支付分发成本);它绝对意味着摆脱关于如何使用它,特别是如何共享它的限制。
Stallman founded the FSF to guarantee that some software would always remain free. Note that Free does not necessarily mean cheap (you may have to pay a fee to cover the cost of distribution); it most definitely does mean liberated from restrictions about how it can be used and specifically how it can be shared.
斯托曼被广泛认为是自由软件运动的创始人,是开源运动的重要前身。 Linux 现在是开源软件最突出的例子,它受 GNU 公共许可证或 GPL 的约束(可在http://www.gnu.org/copyleft/gpl.html在线获取)。 Stallman 认为内核本身之外的大部分 Linux 都是 GNU 软件,因此他将其称为 GNU/Linux。撇开所有争议不谈,斯托曼对开源运动的贡献不容高估。 GNU 软件和按照 GPL 分发的开源软件是全世界开发人员和计算机用户的支柱。
Stallman is widely recognized as the founder of the free software movement, which was an important predecessor of the open source movement. Linux is now the most prominent example of open source software, and it falls under the GNU Public License or GPL (available online at http://www.gnu.org/copyleft/gpl.html). Stallman argues that much of Linux outside the kernel itself is GNU software and so he refers to it as GNU/Linux. All controversies aside, Stallman's contribution to the open source movement cannot be overestimated. GNU software and open source software distributed under the GPL are a mainstay for developers and computer users all over the world.
FSF 的创建正是为了按照鼓励您共享而不是囤积软件的条款分发程序。 GPL 旨在防止一种不幸的常见做法,即公司采用公共域代码,进行一些修改和错误修复,然后对修改后的版本进行版权保护。一旦公司这样做,该程序基本上就成为私有财产并从公共领域消失。斯托曼之所以成立这个基金会,是因为他发现这种做法令人憎恶。正如他在 GNU 宣言中所解释的那样,“出于良心,我不能签署保密协议或软件许可协议……为了让我能够继续使用计算机而不会蒙羞,我决定将足够多的自由软件放在一起,以便我将能够在没有任何非免费软件的情况下生活。”在宣言的其他地方,斯托曼将共享软件称为“程序员之间友谊的基本行为”。他们的软件是免费的,因为它可以共享并且 永远可以共享——不受限制。 FSF 软件不受限制性版权法的约束,而 Stallman 原则上反对这一点。事实上,他创造了 Copyleft一词来描述 FSF 的可共享软件基础。[ 3 ]
The FSF was created precisely to distribute programs under terms that encourage you to share, rather than hoard, software. The GPL is designed to prevent an unfortunately common practice—namely, a company taking public domain code, making a few modifications and bug fixes, and then copyrighting the modified version. Once a company does this, the program has essentially become private property and disappears from the public domain. Stallman formed the foundation because he finds this practice abhorrent. As he explains in the GNU Manifesto, "I cannot in good conscience sign a nondisclosure agreement or a software license agreement . . . So that I can continue to use computers without dishonor, I have decided to put together a sufficient body of free software so that I will be able to get along without any software that is not free." Elsewhere in the manifesto, Stallman calls sharing software the "fundamental act of friendship among programmers." Their software is free because it can be shared and will always be shareable—without restriction. FSF software is not under restrictive copyright laws, which Stallman objects to in principle. In fact, he coined the term copyleft to describe the FSF's sharable software base.[3]
自从 GNU Emacs 首次发布以来,GNU 操作环境的许多其他部分已经就位:C 和 C++ 编译器(gcc和g++)、非常强大的调试器(gdb)、 lex和yacc的替代品(分别称为flex和 bison ) )、Unix shell(bash,代表“Bourne-Again Shell”)、Gimp(与 Adobe PhotoShop 相当的图形工具)、GNOME(Linux 桌面环境)以及许多其他程序和库。许多最初使用 GPL 变体或其他许可方案的重要开源项目都采用了 GPL 作为其许可证,包括 Python、Mozilla 和 Zope。作者 David Wheeler 认为所有开源项目都应该在 GPL 兼容许可证下发布其软件[ 4 ]( 有关他的观点和一些有关 GPL 的统计数据,请参阅http://www.dwheeler.com/essays/gpl-complete.html ) d 软件)。借助 Linux、GNU 工具和其他 GPL 软件,可以拥有符合 FSF 规定的价值观的完整操作环境。
Since GNU Emacs was first released, many other pieces of the GNU operating environment have fallen into place: C and C++ compilers (gcc and g++), a very powerful debugger (gdb), substitutes for lex and yacc (called flex and bison, respectively), a Unix shell (bash, which stands for "Bourne-Again Shell"), the Gimp (a graphics tool comparable to Adobe PhotoShop), GNOME (a desktop environment for Linux), and many other programs and libraries. Many important open source projects that originally used variants of the GPL or other licensing schemes have adopted the GPL as their license, including Python, Mozilla, and Zope. Author David Wheeler argues that all open source projects should release their software under a GPL-compatible license[4] (see http://www.dwheeler.com/essays/gpl-compatible.html for his views and some statistics about GPL'd software). With Linux, GNU tools, and other GPL'd software, it's possible to have a complete operating environment consistent with the values set forth by the FSF.
[ 3 ] FSF 程序(例如 Emacs)通常随商业系统一起分发。即使在这些情况下,通用公共许可证也保证您不受限制地使用和赠送其程序的权利。当然,该许可证不适用于 GNU 工具附带的其他专有软件。
[3] FSF programs such as Emacs are often distributed with commercial systems. Even in these cases, the General Public License guarantees your right to use and give away their programs without restriction. Of course, the license does not apply to other proprietary software with which GNU tools have been shipped.
[ 4 ] GPL 兼容对于许多组织来说是一个重要的区别。正如我们的审阅者 Mike Trent 指出的那样,许多组织根据修改后的 GPL 发布其软件,因为 GPL 的许可证实际上是“病毒式”的。也就是说,如果项目中出现一行 GPL 代码,则整个项目必须是 GPL 代码。这意味着有兴趣保护其资产但仍希望与开源社区共享代码的公司不能在不进行一些修改的情况下使用 GPL。
[4] GPL-compatible is a critical distinction for many organizations. As our reviewer Mike Trent points out, many organizations release their software under a modified GPL because the GPL's license is actually "viral." That is, if one line of GPL'd code appears in a project, the entire project must be GPL'd. This means corporations interested in protecting their assets but still wanting to share code with the open source community cannot use the GPL without some modification.
本书旨在帮助您尽快开始使用 Emacs,无论您是经验丰富的计算机用户还是新手。前两章为您提供了需要了解的基础知识,本书的其余部分以这些基础知识为基础。读完前两章后,您不必连续阅读其余部分;您可以跳至您感兴趣的主题。此外,本书旨在为您提供所需的手持级别;您可以详细阅读这本书,也可以浏览它,查找命令表和示例。
This book is designed to get you started with Emacs as quickly as possible, whether you are an experienced computer user or a novice. The first two chapters give you the basics you need to know, and the rest of the book builds on these basics. After the first two chapters, you don't have to read the rest consecutively; you can skip to the topics that interest you. Additionally, the book is designed to give you just the level of hand-holding you want; you can either read the book in detail or skim it, looking for tables of commands and examples.
以下是您可以采取的一些阅读路径:
Here are some reading paths you could take:
|
如果 If |
读 Read |
|---|---|
|
您是普通用户 You are a casual user |
Preface, Chapter 1-Chapter 3, Chapter 14 |
|
您是程序员或系统管理员 You are a programmer or system administrator |
Preface, Chapter 1-Chapter 5, Chapter 9-Chapter 12 |
|
您是作家或制作人 You are a writer or production person |
前言,第 1 章-第 3 章,第 7 章,第 8 章,第 14 章 Preface, Chapter 1-Chapter 3, Chapter 7, Chapter 8, Chapter 14 |
|
您想要自定义 Emacs You want to customize Emacs |
Chapter 10 and possibly Chapter 11 |
|
您编写 HTML 或 XML You write HTML or XML | |
|
您想要在 Emacs 中使用操作系统命令 You want to use operating system commands in Emacs | |
|
您在 Windows 或 Mac OS X 上使用 Emacs You use Emacs on Windows or Mac OS X |
这些阅读路径仅供参考。 Emacs 是一款巨大的、功能丰富的编辑器。我们已为您将其分为易于消化的部分,因此您不必因其大小和范围而被推迟。学习 Emacs 的最佳方法是循序渐进;现在学习一点,然后当您对它们感到好奇时了解更多功能。如果您需要做某事但不知道如何在 Emacs 中做,Emacs 可能已经做到了;如果没有,你可以学习如何编写一个 Lisp 函数将其添加到 Emacs 中(详细信息请参阅第 11 章)。在线帮助系统是即时了解新功能的绝佳场所;在线帮助将在第 1 章中讨论,并在第 14 章中进行更详细的介绍 。
These reading paths are offered only as a guideline. Emacs is one gigantic, functionally rich editor. We've divided it up into digestible bites for you, so you don't have to be put off by its size and scope. The best way to learn Emacs is incrementally; learn a little now, then learn more features as you get curious about them. If you need to do something and don't know how to do it in Emacs, Emacs probably already does it; if it doesn't, you can learn how to write a Lisp function to add it to Emacs (see Chapter 11 for details). The online help system is an excellent place to learn about new features on the fly; online help is discussed in Chapter 1 and in more detail in Chapter 14.
以下列出了您在雨天可能需要了解的一些功能:
Here's a list of some features you might want to learn about on a rainy day:
如何使用多个 Emacs 缓冲区、窗口和框架(第 4 章)
How to use multiple Emacs buffers, windows, and frames (Chapter 4)
单词缩写模式(第三章)
Word abbreviation mode (Chapter 3)
宏(第 6 章)
Macros (Chapter 6)
如何将功能键映射到 Emacs 命令(第 10 章)
How to map function keys to Emacs commands (Chapter 10)
如何发出(和编辑)shell 命令(第 5 章)
How to issue (and edit) shell commands (Chapter 5)
如何在 Emacs 中组织文件(第 5 章)
How to organize files in Emacs (Chapter 5)
使用ediff比较文件(第12章)
Using ediff to compare files (Chapter 12)
以下是每章内容的快速摘要:
Here's a quick summary of what's in each chapter:
第 1 章,Emacs 基础知识,告诉您如何启动 Emacs 以及如何使用文件。它还提供了在线帮助系统的快速介绍。
Chapter 1, Emacs Basics, tells you how to start Emacs and how to work with files. It also provides a quick introduction to the online help system.
第 2 章,编辑,解释了用于移动、复制和粘贴文本以及撤消更改的命令。它还引入了非常基本的定制。
Chapter 2, Editing, explains commands for moving around, copying and pasting text, and undoing changes. It also introduces very basic customization.
第 3 章,搜索和替换,涵盖更多编辑功能,包括搜索和替换、单词缩写模式和拼写检查。
Chapter 3, Search and Replace, covers more editing features, including search and replace, word abbreviation mode, and spell checking.
第 4 章,使用缓冲区、窗口和框架,描述如何使用多个缓冲区和窗口,包括 Emacs 样式窗口(划分单个操作系统窗口)和传统操作系统窗口(Emacs 称为 框架)。它还讨论了如何在大文件中为您的位置添加书签。
Chapter 4, Using Buffers, Windows, and Frames, describes how to use multiple buffers and windows, both Emacs-style windows (that divide a single OS window) and traditional OS windows (which Emacs refers to as frames). It also discusses how to bookmark your place in large files.
第 5 章,Emacs 作为工作环境,讨论从 Emacs 内部发出命令、处理文件和目录以及使用基本的时间管理工具(例如日历和日记)。
Chapter 5, Emacs as a Work Environment, talks about issuing commands from within Emacs, working with files and directories, and using basic time management tools such as the calendar and diary.
第 6 章,编写宏,讨论使用宏来消除重复任务。
Chapter 6, Writing Macros, discusses using macros to eliminate repetitive tasks.
第 7 章,简单文本格式设置和专业编辑,涵盖基本文本格式设置(例如制表符、缩进和居中)以及一些更稀有的功能,例如轮廓模式和矩形编辑。
Chapter 7, Simple Text Formatting and Specialized Editing, covers basic text formatting (such as tabs, indentation, and centering) as well as some of the more rarefied features, like outline mode and rectangle editing.
第 8 章,标记语言支持,描述 Emacs 对 HTML、XML、TEX 和 LATEX 的支持。
Chapter 8, Markup Language Support, describes Emacs support for HTML, XML, TEX, and LATEX..
第 9 章,计算机语言支持,介绍了作为编程环境的 Emacs,包括对 C、Java、Lisp、Perl 和 SQL 的编辑支持,以及编译器和 Unix make实用程序的接口。它还描述了 Emacs 的 Java 开发环境 (JDEE)。
Chapter 9, Computer Language Support, covers Emacs as a programming environment, including editing support for C, Java, Lisp, Perl, and SQL, as well as the interface to compilers and the Unix make utility. It also describes the Java Development Environment for Emacs (JDEE).
第 10 章,定制 Emacs,描述 Emacs 的定制工具。交互式自定义工具允许您更改变量而无需编辑启动文件。本章还介绍了如何设置.emacs自定义文件。它描述了如何修改显示、键盘命令和编辑环境,以及如何加载 Lisp 包以获得额外功能。
Chapter 10, Customizing Emacs, describes Emacs's customization facilities. The interactive Custom tool allows you to change variables without editing your startup file. The chapter also explains how to set up your .emacs customization file. It describes how to modify your display, keyboard commands, and editing environment as well as how to load Lisp packages for extra functionality.
第 11 章,Emacs Lisp 编程,描述了 Emacs Lisp 的基础知识,您可以使用该语言来进一步自定义 Emacs。
Chapter 11, Emacs Lisp Programming, describes the basics of Emacs Lisp, the language you can use to further customize Emacs.
第 12 章,版本控制,描述用于版本控制的 VC 模式及其与 CVS、RCS、Subversion 和 SCCS 的接口。
Chapter 12, Version Control, describes VC mode for version control and its interface to CVS, RCS, Subversion, and SCCS.
第 13 章,特定于平台的注意事项,讨论如何在 Unix、Windows 和 Mac OS X 上安装 Emacs。它还提供了 Windows 和 Mac OS X 的特定于平台的信息。
Chapter 13, Platform-Specific Considerations, discusses how to install Emacs on Unix, Windows, and Mac OS X. It also provides platform-specific information for Windows and Mac OS X.
第 14 章,帮助系统,描述了 Emacs 丰富、全面的在线帮助工具。
Chapter 14, The Help System, describes Emacs's rich, comprehensive online help facilities.
附录 A,Emacs 变量,列出了许多重要的 Emacs 变量,包括本书中提到的所有变量。
Appendix A, Emacs Variables, lists many important Emacs variables, including all the variables mentioned in this book.
附录 B,Emacs Lisp 软件包,列出了 Emacs 附带的一些最有用的 Lisp 软件包。
Appendix B, Emacs Lisp Packages, lists some of the most useful Lisp packages that come with Emacs.
附录 C,错误和错误修复,告诉您如何(以及何时)报告您在 Emacs 中发现的错误。它还描述了如何为 GNU 项目做出贡献,无论是通过代码增强还是通过金钱。
Appendix C, Bugs and Bug Fixes, tells you how (and when) to report bugs you find in Emacs. It also describes how to contribute to the GNU Project, whether through code enhancements or monetarily.
附录 D,在线资源,介绍了一些重要的 Emacs 相关网站。
Appendix D, Online Resources, gives a tour of some important Emacs-related web sites.
附录 E,快速参考,提供了本书中讨论的最重要的 Emacs 命令的简要描述。
Appendix E, Quick Reference, provides brief descriptions of the most important Emacs commands discussed in this book.
本书最后提供了一个词汇表,其中定义了您将遇到的 Emacs 术语、一个索引和一张可拆卸的快速参考卡,其中总结了重要命令以便于访问。
The book concludes with a glossary that defines Emacs terms you'll encounter, an index, and a detachable quick reference card that summarizes important commands for easy access.
GNU Emacs 是一个大型且功能强大的编辑器;在本书中,我们仅向您提供其功能的一个示例。许多功能被遗漏了,并且一直在添加更多功能。然而,有些主题并未涵盖:
GNU Emacs is a large and powerful editor; in this book, we give you only a sample of what it does. Many features have been left out, and more features are added all the time. Some topics, however, are not covered:
例如, GNU Emacs 为vi提供了兼容模式。我们省略了对这些模式的讨论。如果您确实想使用vi或其他编辑器,请这样做。您最好按照 Emacs 本身的方式来了解它,而不是假装它是其他东西。
GNU Emacs provides compatibility modes for vi, for example. We've left a discussion of these modes out. If you really want to use vi or another editor, do so. You're better off getting to know Emacs on its own terms rather than pretending it is something else.
在本书中,我们讨论 C++、Java、Lisp、Perl 和 SQL 的编辑模式。其他语言有很多模式,包括像Scheme这样的罕见语言。我们不可能讨论所有事情。
In this book, we discuss editing modes for C++, Java, Lisp, Perl, and SQL. There are many modes for other languages, including rare languages like Scheme. There's no way we could discuss everything.
GNU Emacs 包含一个完整的 Lisp 解释器。我们对 Emacs Lisp 进行了非常基础和简短的介绍;第 11 章应该足以帮助您入门,但它实际上只触及了表面。我们推荐 FSF 的Emacs Lisp 参考手册,现已包含在 Emacs 发行版中。
GNU Emacs incorporates a complete Lisp interpreter. We give a very basic and brief introduction to Emacs Lisp; Chapter 11 should be enough to get you started, but it really only scratches the surface. We recommend the FSF's Emacs Lisp Reference Manual, now included in the Emacs distribution.
当我们的上一版本发布时,使用 Emacs 访问互联网资源或阅读电子邮件很常见。现在这种情况已经不那么常见了;所有平台上都普遍使用更好的邮件程序、浏览器和其他工具。
When our last edition came out, it was common to use Emacs to access Internet resources or read email. Now that isn't so common; better mailers, browsers, and other tools are commonly in use on all platforms.
目前,Emacs 正在全面支持 Unicode;这是下一个主要版本中最重要的变化。在撰写本文时,Unicode 支持还不稳定。
At present, Emacs is on its way to full Unicode support; that is the most important change slated for the next major release. At this writing, Unicode support is spotty.
GNU Emacs 包含一系列不拘一格的游戏和娱乐,包括将 Zippy the Pinhead 的随机引言传送到著名的“Eliza”伪精神分析师的能力。 Emacs 21 在“工具”下包含一个“游戏”菜单,其中提供了几种在 Emacs 中消磨时间的很酷的方法(它甚至不包括我们最喜欢的 Emacs 版本的 pong)。唉,我们必须在某个地方划清界限。
GNU Emacs includes an eclectic bunch of games and amusements, including the ability to pipe random quotations from Zippy the Pinhead into the famous "Eliza" pseudopsychoanalyst. Emacs 21 includes a Games menu under Tools with several cool ways to waste time in Emacs (and it doesn't even include Emacs's version of pong, one of our favorites). Alas, we had to draw the line somewhere.
Emacs 命令由修饰符(例如Control )和一系列击键组成,您可以像按住Shift键一样按住它 。例如,Control-x Control-s保存文件。
Emacs commands consist of a modifier, such as Control, which you hold down as you would the Shift key, and a series of keystrokes. For example, Control-x Control-s saves a file.
Emacs 使用的另一个修饰符是 元键。很少有键盘有标记为Meta 的键。因此,在本书的前几个版本中,我们拒绝谈论 Meta键,并在所有说明中用Esc代替。
The other modifier Emacs uses is the Meta key. Few keyboards have keys labeled Meta. Because of this, in previous editions of this book, we refused to talk about the Meta key and substituted Esc in all our instructions.
在这个版本中,我们希望您了解Meta键在哪里。通常, 元键位于空格键的左侧和右侧。在 Linux 和 Windows 键盘上, Alt键是Meta键。在 Mac 键盘上,Apple键(通常称为Command)默认为Meta键。
In this edition, we want you to learn where the Meta key is. Typically Meta keys are to the immediate left and right of the Space bar. On Linux and Windows keyboards, the Alt key is the Meta key. On Mac keyboards, the Apple key, often called Command is the Meta key by default.
为什么要了解并使用Meta 键?原因是速度。我们在本书中强调键绑定。新用户可能会发现图标和菜单很有帮助,但从长远来看,学习如何将手放在键盘上可以让您提高速度并提高工作效率。 Meta 键将帮助您提高速度,并让您轻松使用 Emacs 帮助(指Meta )。
Why learn about and use the Meta key? The reason is speed. We emphasize key bindings in this book. New users may find icons and menus helpful, but in the long run, learning how to keep your hands on the keyboard allows you to gain speed and boosts your productivity. The Meta key will help you gain that speed and make it easy for you to use Emacs help, which refers to Meta.
根据您的风格,您可能仍然更喜欢使用Esc而不是Meta。请记住,使用Esc 键按下并释放该键,然后按下一个键。
Depending on your style, you may still prefer to use Esc instead of Meta. Just bear in mind that with Esc you press and release the key, then press the next key.
本节介绍本书中使用的约定。
This section covers the conventions used in this book.
Emacs 命令由修饰符(例如Ctrl 或Meta)和后跟一两个字符组成。本书中显示的命令将Ctrl缩写为C ,将Meta缩写为M:
Emacs commands consist of a modifier, such as Ctrl or Meta, followed by one or two characters. Commands shown in this book abbreviate Ctrl to C and Meta to M:
按住Ctrl键并按 g。
Hold down the Ctrl key and press g.
按住Meta键并按 x。
Hold down the Meta key and press x.
有时Meta 后面会跟一个字面连字符。在这些情况下,我们会拼写出Meta:
Sometimes Meta is followed by a literal hyphen character. In these cases, we spell out Meta:
按住Meta键并按 -。
Hold down the Meta key and press -.
要完成命令,您可能需要按Enter。 (此键可能标记为Return。)
To complete a command you may need to press Enter. (This key may be labeled Return.)
按Enter键。
Press the Enter key.
可以用作Meta的替代品。按Esc,松开,然后按下一个键。
Can be used as an alternative to Meta. Press Esc, release it, then press the next key.
一些鼠标命令使用Shift键作为修饰键,通常与Ctrl键 结合使用。这缩写为:
A few mouse commands use the Shift key as a modifier, often in combination with the Ctrl key. This is abbreviated as:
按住Shift 键并单击鼠标右键。
Hold down Shift and click the right mouse button.
按住Shift和Ctrl 键并单击鼠标右键。
Hold down Shift and Ctrl and click the right mouse button.
所有 Emacs 命令,即使是最简单的命令,都有一个全名;例如,forward-word相当于击键Mf,forward-char相当于Cf。这种命令与击键组合的绑定称为键绑定。有些命令只有全名,没有相应的键绑定。
All Emacs commands, even the simplest ones, have a full name; for example, forward-word is equivalent to the keystrokes M-f, and forward-char is equivalent to C-f. This tying of a command to a keystroke combination is called a key binding. Some commands have only full names, with no corresponding key binding.
当我们讨论命令时,我们将给出它的全名以及您可以键入来调用它的击键(如果有)。
When we discuss a command, we'll give both its full name and the keystrokes (if any) that you can type to invoke it.
要快速找到一组命令,请在每个部分中查找总结命令的表格。这些表的格式如下:
To find a group of commands quickly, look for tables in each section that summarize commands. These tables are formatted like this:
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
中文 C-n |
下一行 next-line |
移至下一行。 Move to the next line. |
|
Cx Cf 文件 → 打开文件 C-x C-f File → Open File |
查找文件 find-file |
打开指定文件。 Open a specified file. |
|
(没有任何) (none) |
哟 yow |
在迷你缓冲区中打印来自针头的难以言喻的智慧。 Print ineffable wisdom from the Pinhead in the minibuffer. |
第一列显示命令的默认键绑定,第二列显示命令的全名,第三列描述命令的作用。例如,按 Cn(也称为下一行命令)会将光标移动到文件中的下一行。某些命令(例如Cx Cf)也可以通过菜单访问。如果特定命令有菜单选项,则会在 该命令的击键下方以斜体字给出。例如,您可以通过键入Cx Cf或从“文件”菜单中选择“打开文件”来使用find-file命令。有时您会在击键列中看到 ( none ),这并不意味着您不能使用该命令,而是该命令未绑定到特定的击键。要使用无需击键的命令,请键入 Mx,后跟命令的全名,然后按Enter。 (有时尝试输入Mx pong Enter。)
The first column shows the default key binding for the command, the second column shows the command's full name, and the third column describes what the command does. For example, pressing C-n (also known as the next-line command) moves the cursor to the next line in the file. Some commands, like C-x C-f, can also be reached through menus. If there is a menu option for a particular command, it is given in italics below the keystrokes for the command. For example, you can use the find-file command by typing C-x C-f or by selecting Open File from the File menu. Sometimes you'll see (none) in the keystrokes column, which doesn't mean you can't use the command, but rather that the command isn't bound to particular keystrokes. To use commands with no keystrokes, type M-x, followed by the command's full name, and press Enter. (Try typing M-x pong Enter sometime.)
在整本书中,您将找到要输入的按键,然后是显示结果的屏幕截图。
Throughout the book, you'll find keystrokes to type, followed by a screenshot showing the results.
|
类型:Cx Cf
Type: C-x C-f
|
|
|
|
使用find-file命令打开文件或创建新文件。 Use the find-file command to open a file or create a new file. |
Cx Cf以粗体显示,表明这正是您键入的内容。myfile以等宽斜体显示,因为您可以替换您选择的任何文件名,而无需准确键入您在此处看到的内容。
C-x C-f is in bold, indicating that
this is exactly what you type. myfile is
shown in constant width italics because you could substitute any
filename you choose and need not type exactly what you see here.
通常,这些屏幕截图来自 Linux 系统。我们还提供了在 Mac OS X 和 Windows 上拍摄的屏幕截图。当我们显示此类屏幕截图时,我们会在屏幕截图的标题中包含平台的指示。
Typically, these screenshots come from a Linux system. We also include screenshots taken on Mac OS X and Windows. When we show such screenshots, we include an indication of the platform in the caption for the screenshot.
在本书的最后,当我们讨论编程模式、定制和 Lisp 编程时,屏幕截图变得相当笨拙。我们最终会使用更少的它们。相反,我们可能会显示一两行文本。如果相关,我们显示光标的位置:
Toward the end of the book, when we're discussing programming modes, customization, and Lisp programming, screenshots become rather unwieldy. We eventually use fewer of them. Instead, we may show one or two lines of text. If it's relevant, we show the cursor's position:
/*这是一个c注释*//* This is a c comment */本书使用以下字体约定:
This book uses the following font conventions:
指示操作系统命令、Emacs 击键、命令名称和变量。
Indicates operating system commands, Emacs keystrokes, command names, and variables.
指示首次引入时的文件名、URL 和新术语。
Indicates filenames, URLs, and new terms when first introduced.
constant width
constant width
指示缓冲区名称、Lisp 代码、C 代码、Emacs 消息以及程序的其他摘录。
Indicates buffer names, Lisp code, C code, Emacs messages, and other excerpts from programs.
constant width italic
constant width italic
指示您替换为实际值的虚拟参数。有时也可能显示在尖括号 (<文件名>) 中。
Indicates dummy parameters that you replace with an actual value. May also be shown sometimes in angle brackets (<filename>).
我们已尽最大努力测试和验证了本书中的信息,但您可能会发现功能发生了变化(甚至我们犯了错误!)。请写信至以下地址,告知我们您发现的任何错误以及您对未来版本的建议:
We have tested and verified the information in this book to the best of our ability, but you may find that features have changed (or even that we have made mistakes!). Please let us know about any errors you find, as well as your suggestions for future editions, by writing to:
| 奥莱利媒体公司 |
| 格拉文斯坦公路北1005号 |
| 塞瓦斯托波尔, CA 95472 |
| 1-800-998-9938(美国或加拿大) |
| 1-707-829-0515(国际/本地) |
| 1-707-829-0104(传真) |
要提出技术问题或对本书发表评论,请发送电子邮件至:
To ask technical questions or comment on the book, send email to:
我们有一个关于这本书的网站,我们将在其中列出示例、勘误表以及未来版本的任何计划。您可以通过以下地址访问此页面:
We have a web site for the book, where we'll list examples, errata, and any plans for future editions. You can access this page at:
http://www.oreilly.com/catalog/gnu3/
http://www.oreilly.com/catalog/gnu3/
当您在您喜爱的技术书籍的封面上看到启用 Safari® 的图标时,这意味着该书可通过 O'Reilly Network Safari 书架在线获取。
When you see a Safari® enabled icon on the cover of your favorite technology book that means the book is available online through the O'Reilly Network Safari Bookshelf.
Safari 提供了比电子书更好的解决方案。它是一个虚拟图书馆,可让您轻松搜索数千本顶级技术书籍、剪切和粘贴代码示例、下载章节,并在需要最准确的最新信息时快速找到答案。请访问http://safari.oreilly.com免费试用。
Safari offers a solution that's better than e-Books. It's a virtual library that let's you easily search thousands of top tech books, cut and paste code samples, download chapters, and find quick answers when you nee the most accurate, current information. Try it free at http://safari.oreilly.com.
有关本书和其他书籍的更多信息,请访问 O'Reilly 网站:
For more information about this book and others, see the O'Reilly web site:
您还可以将有关 Emacs 的问题和有关本书的建议发送至deb@oreilly.com。
You can also send questions about Emacs and suggestions about this book to deb@oreilly.com.
Debra Cameron:首先,我要感谢 Duffy Craven 向我介绍 Emacs。其次,我要感谢我的合著者。比尔·罗森布拉特 (Bill Rosenblatt) 对本书的第一版提供了巨大的帮助,而埃里克·雷蒙德 (Eric Raymond) 在第二版上的工作速度惊人,才华横溢,同时也为第三版提供了一些意见。我要特别感谢我的合著者 Jim Elliott 和 Marc Loy,老实说,没有他们,第三版就不可能完成。他们不断的鼓励、支持和辛勤工作使这一版本成为现实。我要感谢所有来信提出建议的读者,特别是 Russell Harris、Seema Kumar 和 Hui Olan。我还要感谢 Eric Pement,他向我介绍了非常有趣的 TEI Emacs 附加组件,以及该 Emacs 扩展环境的作者,包括 Sebastian Rahtz 和 Syd Bauman。就我个人而言,我要感谢我的丈夫吉姆和我的孩子梅格、大卫、贝丝和凯文在本书修订过程中的耐心和帮助,也感谢我的朋友艾琳和杰基的支持。最重要的是,我要感谢所有开发人员和黑客,他们继续使 GNU Emacs 成为我使用过的最令人惊奇的软件。
Debra Cameron: First, I would like to thank Duffy Craven for introducing me to Emacs. Second, I would like to thank my coauthors. Bill Rosenblatt was a tremendous help on the first edition of this book, and Eric Raymond worked with blinding speed and brilliance on the second, providing some input on the third as well. I would especially like to thank my coauthors Jim Elliott and Marc Loy, without whom, in all honesty, this third edition would never have been finished. Their constant encouragement, support, and hard work helped make this edition a reality. I would like to thank all the readers who wrote in with their suggestions, especially Russell Harris, Seema Kumar, and Hui Oulan. I would also like to thank Eric Pement, who pointed me to the very interesting TEI Emacs add-on, as well as the authors of that extended environment for Emacs, including Sebastian Rahtz and Syd Bauman. Personally, I would like to thank my husband Jim and my kids Meg, David, Beth, and Kevin for their patience and help during the revision of this book and also my friends Irene and Jacki for their support. Most of all, I would like to thank all the developers and hackers who continue to make GNU Emacs the most amazing piece of software I have ever worked with.
James Elliott:我必须感谢 Deb 让我帮助人们了解 Emacs。我长期以来一直钦佩(并依赖)该编辑器及其不断增长的工具和扩展生态系统,以及自由软件基金会的理念和成果。它们代表了计算对我来说是一个有趣且有价值的领域的精华,我很荣幸能成为这个项目的一部分。具有讽刺意味的是,我还必须感谢 Deb 在我的 Hibernate 书问世时让我休息了很多时间。
James Elliott: I have to thank Deb for asking me to help people learn about Emacs. I've long admired (and relied on) the editor and its ever-growing ecosystem of tools and extensions, as well as the philosophy and results of the Free Software Foundation. They represent a distillation of what makes computing an interesting and valuable field for me, and I am honored to be part of this project. Ironically, I have to also thank Deb for letting me take a big chunk of time off when my Hibernate book came into being.
还要感谢 Marc,他最初将我介绍给 O'Reilly 的优秀人员,也感谢他对本书的帮助和投入。当我在中间被拉走时,他最终贡献的钱比他报名的要多。我也不应该忘记纽约 Niskayuna GE 公司研发中心的优秀同事,他们在我实习期间首先向我介绍了 Emacs 的奥秘。我感谢乔的爱和支持。让我们聆听成千上万将 Emacs 发展成今天的样子的演员们的声音!
Thanks are also due to Marc, both for initially introducing me to the fine folks at O'Reilly and for his help and input on this book. He ended up contributing more than he signed up for when I got pulled away in the middle. Nor should I forget my fine colleagues at GE's Corporate Research and Development Center in Niskayuna, New York who first introduced me to the mysteries of Emacs as an intern there. I'm indebted to Joe for his love and support. And let's hear it for the cast of thousands who have grown Emacs into what it is today!
Marc Loy:我要感谢南加州大学计算机实验室那些偶尔偷懒(不,可以说是过度劳累)的工作人员,他们让我开始使用 Emacs。当我坐下来编写我的第一个计算机程序时, vi备忘单已经用完了(我不会承认我必须使用的语言。)从那时起我就一直对这件事心存感激。我还要感谢吉姆和黛布在我们完成最新版本时对事物的乐观看法。和往常一样,我的妹妹 Amy 和我的搭档 Ron 仍然是我世界中永远向善的力量,让围绕有趣的东西(比如写 Emacs)的所有愚蠢行为(比如政治)变得可以忍受。
Marc Loy: I have the occasionally lazy—no, let's say overworked—staff at the University of Southern California's computer labs to thank for getting me started on Emacs. They were out of vi cheat sheets when I sat down to write my first computer program. (I won't admit to the language I had to use.) I've been grateful for that happenstance ever since. I'd also like to thank Jim and Deb for their cheery outlook on things as we finished up this latest edition. As always, my sister Amy and my partner Ron remain constant forces for good in my world and make all the silliness (like politics) surrounding the fun stuff (like writing about Emacs) tolerable.
Eric Raymond:我首先要感谢整个黑客社区,所有创造了 Emacs Lisp 编程丰富传统的人,将 Emacs 定制从优雅的理论可能性变成了实用工具。我的部分知识是通过阅读 Olin Shivers、Jamie Zawinski、Kyle Jones、Barry Warsaw、Roland McGrath、Richard Stallman 本人(当然)以及其他许多人编写的代码而学到的。其次,我一如既往地感谢我的妻子凯瑟琳,并给予我最热烈的爱,在我完成本书的工作时,她在很多层面上支持了我。最后,我对 O'Reilly 那些时髦、专业、聪明的人们表示感谢和敬意。他们知道如何写出一本好书,以及如何正确对待作者。他们很关心,这一点也体现出来了。
Eric Raymond: My thanks go first to the hacker community at large, all the people who created the rich tradition of Emacs Lisp programming that takes Emacs customization from elegant theoretical possibility to practical tool. I learned what I know partly from reading code written by the likes of Olin Shivers, Jamie Zawinski, Kyle Jones, Barry Warsaw, Roland McGrath, Richard Stallman himself (of course), and many others. Secondly, my thanks and warmest love go as always to my wife Catherine, who supported me on many levels while I worked on my bits of this book. Finally, my thanks and respect to the hip, professional, and clueful people at O'Reilly. They know how to produce a good book and how to treat an author right. They care, and it shows.
比尔·罗森布拉特:我要感谢以下人:理查德·马丁教授(普林斯顿大学古典系),他在我心中种下了种子,最终使写作从苦差事变成了乐趣; Intermetrics, Inc. 给了我足够的时间来研究 GNU Emacs;哈尔·斯特恩(Hal Stern)为我安排了这次演出;桑迪·怀斯,感谢他的帮助;杰西卡·勒斯蒂格,感谢她的爱和支持;最重要的是,我的研究生室友们忍受了日夜不停的电话线。
Bill Rosenblatt: I would like to thank the following people: Professor Richard Martin (Princeton Classics Department), for planting the seed in me that eventually turned writing from a chore to a pleasure; Intermetrics, Inc., for giving me little enough to do that I could fritter away my workdays delving into GNU Emacs; Hal Stern, for getting me this gig; Sandy Wise, for his help; Jessica Lustig, for her love and support; and most importantly, my grad-school housemates for putting up with a tied-up phone line at all hours of the day and night.
你们中的一些人可能渴望把手放在键盘上开始打字。我们不会试图阻止你;转到“启动 Emacs”部分,您可以继续。但是,当您准备休息时,请稍后再阅读本章的开头部分。如果您了解所涉及的一些基本概念(我们将在下面的介绍中讨论),那么 Emacs 会更容易学习。
Some of you out there are probably dying to get your hands on the keyboard and start typing. We won't try to stop you; turn to the section called "Starting Emacs" and you can go ahead. But do read the beginning of this chapter later when you're ready for a break. Emacs is much easier to learn if you understand some of the basic concepts involved, which we discuss in the following introduction.
GNU Emacs 是其中之一 当今世界上最常用的文本编辑器。与vi(Unix 的标准编辑器)或其他 GUI 文本编辑器相比,许多用户更喜欢 Emacs 。为什么 Emacs 如此受欢迎?它不是最新的工具,当然也不是最漂亮的。但它很可能是您学到的最有用的工具。我们希望向您展示您需要了解的有关 Emacs 的知识,以便您能够有效地使用它来完成有用的工作。本书是 Emacs 用户的指南;它试图满足许多读者的需求,从临时用户到程序员。
GNU Emacs is one of the most commonly used text editors in the world today. Many users prefer Emacs to vi (Unix's standard editor) or to other GUI text editors. Why is Emacs so popular? It isn't the newest tool, and it's certainly not the prettiest. But it may well be the most useful tool you'll ever learn. We want to present what you need to know about Emacs to do useful work, in a way that lets you use it effectively. This book is a guide for Emacs users; it tries to satisfy the needs of many readers, ranging from casual users to programmers.
因此,我们的方法并不是告诉您 Emacs 所做的一切。它有许多本书没有描述的功能和命令。我们认为这不是问题; Emacs 有一个全面的在线帮助工具,可以帮助您了解这些是什么。我们将注意力集中在描述如何完成有用的工作上。在前三章介绍了基本编辑之后,我们将描述如何使用 Emacs 作为一个综合工作环境:如何使用多个缓冲区和窗口来提高生产力,如何在不离开编辑器的情况下发出命令,如何利用特殊的编辑模式,如何使用Emacs编辑特殊类型的文件(各种编程语言的源文件)等等。我们涵盖了最重要的命令和最重要的编辑模式。然而,您应该始终牢记一个原则:Emacs 在很多事情上做得很好,但这并不重要。 Emacs 很重要,因为它集成了您需要做的不同事情。
Our approach therefore isn't to tell you absolutely everything that Emacs does. It has many features and commands that this book doesn't describe. We don't think that's a problem; Emacs has a comprehensive online help facility that helps you figure out what these are. We focus our attention on describing how to get useful work done. After covering basic editing in the first three chapters, we describe how to use Emacs as a comprehensive working environment: how to boost productivity with multiple buffers and windows, how to give commands without leaving the editor, how to take advantage of special editing modes, how to use Emacs for editing special types of files (source files for various programming languages), and so on. We cover the most important commands and the most important editing modes. However, you should always keep one principle in mind: Emacs does many things well, but it isn't important for that reason. Emacs is important because of the integration of different things you need to do.
整合意味着什么?一个简单的 例子会有所帮助。假设有人向您发送一封邮件消息,描述用于访问新打印机的特殊命令。您可以启动 Emacs shell,将命令粘贴到 Emacs 中,然后直接执行。如果有效,您可以编辑启动文件来为该命令创建别名。您无需离开编辑器也无需重新输入命令一次即可完成所有这些操作。这就是 Emacs 如此强大的原因。它不仅仅是一个编辑器;这是一个可以改变您工作方式的完整环境。
What does integration mean? A simple example will help. Assume that someone sends you a mail message describing a special command for accessing a new printer. You can fire up an Emacs shell, paste the command into Emacs, and execute it directly. If it works, you can edit your startup file to create an alias for the command. You can do all this without leaving the editor and without having to retype the command once. That's why Emacs is so powerful. It's more than just an editor; it's a complete environment that can change the way you work.
也是最初的建议。很多人认为Emacs是一个极难学的编辑器。我们不明白为什么。诚然,它有很多功能,但您可能永远不会使用所有这些功能。但任何编辑器,无论多么简单或复杂,都具有相同的基本功能。如果你能学会一个,你就可以学会其中任何一个。我们将为您提供标准的助记符设备,帮助您记住命令(例如“ Cp表示上一行”),但我们实际上认为这些都是不必要的。它们可以帮助你克服学习过程中的最初困难,但从长远来看并没有多大区别。学习使用编辑器基本上就是学习手指习惯:学习在哪里将手指移至上一行。如果您尝试使用 Emacs 并尝试输入我们的一些示例,您将很快养成这些手指习惯。当你养成这些习惯后,你将永远不会忘记,就像你永远不会忘记如何骑自行车一样。使用 Emacs 一两天后,我们再也不用想“ Cp意味着上一行”。我们的手指知道该去哪里。一旦你到了这一步,你就到家了。您可以利用 Emacs 发挥创造力,并开始思考如何利用其功能为您服务。 Emacs 具有丰富的菜单,但我们仍然建议学习常用命令的键绑定。良好的手指习惯可以让你成为一名速度惊人的打字员,而从键盘到鼠标只会减慢你的速度。
An initial word of advice, too. Many people think that Emacs is an extremely difficult editor to learn. We don't see why. Admittedly, it has a lot of features, and you probably will never use all of them. But any editor, no matter how simple or complex, has the same basic functions. If you can learn one, you can learn any of them. We'll give you the standard mnemonic devices that will help you remember commands (like "C-p means previous line"), but we really don't think even these are necessary. They get you over an initial hump in the learning process but don't make much difference in the long run. Learning to use an editor is basically a matter of learning finger habits: learning where to put your fingers to move to the previous line. If you experiment with Emacs and try typing a few of our examples, you'll quickly acquire these finger habits. And after you've acquired these habits, you'll never forget, any more than you'll forget how to ride a bicycle. After using Emacs for a day or two, we never had to think, "C-p means previous line." Our fingers just knew where to go. Once you're at this point, you're home. You can become creative with Emacs and start thinking about how to put its features to work for you. Emacs has extensive menus, but we still recommend learning the key bindings for commonly used commands. Good finger habits can make you an incredibly fast typist, and reaching from keyboard to mouse only slows you down.
手指习惯方法也意味着阅读本书的不同方式。从智力上来说,你可以从一篇阅读中吸收很多东西,但你每天只能养成一些新习惯。 (当然,除非它们是坏习惯。)第 2 章涵盖了您将使用的大部分基本编辑技术。您可能需要阅读几次,每次的重点略有不同。例如,Emacs 为您提供了多种不同的前进方式:您可以前进一个字符、一个单词、一行、一句话、一段、一页等等。所有这些技术都在第 2 章中介绍。首先学习如何前进和后退,然后逐渐添加更复杂的命令。类似地,Emacs 提供了许多不同的技术来搜索文件,这将在第 3 章中介绍。不要觉得有必要一次性学习它们;选择一些东西,练习它,然后继续下一个主题。如果您必须多次阅读本书的前三章才能感到舒服,没有人会抱怨。花时间培养好习惯是值得的。
The finger-habits approach also implies a different way of reading this book. Intellectually, it's possible to absorb a lot from one reading, but you can form only a few new habits each day. (Unless, of course, they're bad habits.) Chapter 2 covers most of the basic editing techniques you'll use. You may need to read it several times, with a slightly different focus each time. For example, Emacs gives you many different ways to move forward: you can move forward one character, one word, one line, one sentence, one paragraph, one page, and so on. All of these techniques are covered in Chapter 2. Start by learning how to move forward and backward, then gradually add more complex commands. Similarly, Emacs provides many different techniques for searching through a file, covered in Chapter 3. Don't feel obliged to learn them all at once; pick something, practice it, and move on to the next topic. No one will complain if you have to work through the first three chapters of our book several times before you're comfortable. Time spent developing good habits is time well spent.
你真的不
使用 Emacs 编辑文件。相反,Emacs 将文件的内容复制到临时缓冲区中,然后您对其进行编辑。在保存缓冲区之前,磁盘上的文件不会更改。与文件一样,Emacs 缓冲区也有名称。缓冲区的名称通常与您正在编辑的文件的名称相同。有一些例外。有些缓冲区没有关联的文件——例如,*scratch*只是一个临时练习缓冲区,如便签本;帮助工具在名为 的缓冲区中显示帮助消息
*Help*,该缓冲区也未连接到文件。
You don't really
edit
files with Emacs. Instead, Emacs copies the contents of a file into a
temporary buffer and you edit that. The file on disk
doesn't change until you save the buffer. Like
files, Emacs buffers have names. The name of a buffer is usually the
same as the name of the file that you're editing.
There are a few exceptions. Some buffers don't have
associated files—for example, *scratch* is
just a temporary practice buffer, like a scratchpad; the help
facility displays help messages in a buffer named
*Help*, which also isn't
connected to a file.
Emacs实现它的一些著名的多功能性是通过具有不同的编辑模式来实现的,在这些模式中它的行为略有不同。模式这个词听起来可能很技术性,但它真正的意思是 Emacs 对手头的任务变得敏感。当您写作时,您通常需要自动换行等功能,这样您就不必在每行末尾按Enter键。编程时,必须根据语言正确设置代码格式。对于写作,有文本模式;对于编程,有针对不同语言的模式,包括 C、Java 和 Perl。那么,模式让 Emacs 成为您想要完成不同任务的编辑器。
Emacs achieves some of its famed versatility by having various editing modes in which it behaves slightly differently. The word mode may sound technical, but what it really means is that Emacs becomes sensitive to the task at hand. When you're writing, you often want features like word wrap so that you don't have to press Enter at the end of every line. When you're programming, the code must be formatted correctly depending on the language. For writing, there's text mode; for programming, there are modes for different languages, including C, Java, and Perl. Modes, then, allow Emacs to be the kind of editor you want for different tasks.
文本模式和Java模式是 主要模式。一个缓冲区一次只能处于一种主要模式;要退出一种主要模式,您必须进入另一种模式。表 1-1列出了一些主要模式、它们的用途以及 本书将介绍这些内容。
Text mode and Java mode are major modes. A buffer can be in only one major mode at a time; to exit a major mode, you have to enter another one. Table 1-1 lists some of the major modes, what they do, and where they're covered in this book.
表 1-1。主要模式
Table 1-1. Major modes
|
模式 Mode |
功能 Function |
|---|---|
|
基本模式 Fundamental mode |
默认模式(第6章) The default mode (Chapter 6) |
|
文本模式 Text mode |
用于编写文本(第 2 章) For writing text (Chapter 2) |
|
查看模式 View mode |
用于查看文件但不进行编辑(第 4 章) For viewing files but not editing (Chapter 4) |
|
外壳模式 Shell mode |
用于在 Emacs 中运行 shell(第 5 章) For running a shell within Emacs (Chapter 5) |
|
轮廓模式 Outline mode |
用于撰写大纲(第 7 章) For writing outlines (Chapter 7) |
|
缩进文本模式 Indented text mode |
用于自动缩进文本(第 7 章) For indenting text automatically (Chapter 7) |
|
段落缩进文本模式 Paragraph indent text mode |
用于缩进每段的第一行(第7章) For indenting the first line of each paragraph (Chapter 7) |
|
图片模式 Picture mode |
使用键盘创建 ASCII 绘图(第 7 章) For creating ASCII drawings using the keyboard (Chapter 7) |
|
HTML模式 HTML mode |
用于编写 HTML(第 8 章) For writing HTML (Chapter 8) |
|
SGML模式 SGML mode |
用于编写 SGML 和 XML(第 8 章) For writing SGML and XML (Chapter 8) |
|
乳胶模式 LaTeX mode |
用于 TEX 和 LATEX 的格式化文件(第 8 章) For formatting files for TEX and LATEX (Chapter 8) |
|
编译模式 Compilation mode |
用于编译程序(第9章) For compiling programs (Chapter 9) |
|
抄送模式 cc mode |
用于编写 C、C++ 和 Java 程序(第 9 章) For writing C, C++, and Java programs (Chapter 9) |
|
Java模式 Java mode |
用于编写Java程序(第9章) For writing Java programs (Chapter 9) |
|
Perl模式和Cperl模式 Perl mode and Cperl mode |
用于编写 Perl 程序(第 9 章) For writing Perl programs (Chapter 9) |
|
SQL模式 SQL mode |
使用 SQL 与数据库交互(第 9 章) For interacting with databases using SQL (Chapter 9) |
|
Emacs Lisp 模式 Emacs Lisp mode |
用于编写 Emacs Lisp 函数(第 9 章和第11 章) For writing Emacs Lisp functions (Chapter 9 and Chapter 11) |
|
口齿不清模式 Lisp mode |
For writing Lisp programs (Chapter 9 and Chapter 11) |
|
Lisp交互模式 Lisp interaction mode |
For writing and evaluating Lisp expressions (Chapter 9 andChapter 11) |
每当您编辑文件时, Emacs 尝试将您设置为适合您要编辑的内容的正确主要模式。如果您编辑以.c结尾的文件,它会将您置于抄送模式。如果您编辑以.el结尾的文件 ,它会将您置于 Lisp 模式。有时它会查看文件的内容而不仅仅是其名称。如果您编辑 TEX 格式的文件,Emacs 会将您置于 LaTeX 模式。如果它无法告诉您应该处于哪种模式,它会将您置于基本模式,即最一般的模式。由于 Emacs 是可扩展的,因此也可以使用外接程序模式;我们在本书中讨论了一些内容,尽管我们没有在表 1-1中列出它们。
Whenever you edit a file, Emacs attempts to put you into the correct major mode for what you're going to edit. If you edit a file that ends in .c, it puts you into cc mode. If you edit a file that ends in .el, it puts you in Lisp mode. Sometimes it looks at the contents of the file rather than just its name. If you edit a file formatted for TEX, Emacs puts you in LaTeX mode. If it cannot tell what mode you should be in, it puts you in fundamental mode, the most general of all. Because Emacs is extensible, add-in modes are also available; we talk about some in this book, though we do not list them in Table 1-1.
除了主要模式外 还有一些小模式。这些定义了 Emacs 行为的特定方面,并且可以在主要模式中打开和关闭。例如,自动填充模式意味着 Emacs 应该自动换行;当您输入长行时,它应该自动进行适当的换行。表 1-2列出了一些次要模式、它们的作用以及它们的覆盖范围 这本书。
In addition to major modes there are also minor modes. These define a particular aspect of Emacs's behavior and can be turned on and off within a major mode. For example, auto-fill mode means that Emacs should do word wrap; when you type a long line, it should automatically make an appropriate line break. Table 1-2 lists some minor modes, what they do, and where they're covered in this book.
表 1-2。小调模式
Table 1-2. Minor modes
|
模式 Mode |
功能 Function |
|---|---|
|
自动填充模式 Auto-fill mode |
启用自动换行(第 2 章)。 Enables word wrap (Chapter 2). |
|
覆盖模式 Overwrite mode |
在您键入时替换字符而不是插入它们(第 2 章)。 Replaces characters as you type instead of inserting them (Chapter 2). |
|
自动保存模式 Auto-save mode |
每隔一段时间自动将您的文件保存在一个特殊的自动保存文件中(第 2 章)。 Saves your file automatically every so often in a special auto-save file (Chapter 2). |
|
搜索模式 Isearch mode |
用于搜索(第 3 章)。 For searching (Chapter 3). |
|
飞咒模式 Flyspell mode |
用于 Flyspell 拼写检查器(第 3 章)。 For flyspell spell-checker (Chapter 3). |
|
Flyspell 编程模式 Flyspell prog mode |
用于使用 Flyspell 进行拼写检查的程序(第 3 章)。 For spell-checking programs with flyspell (Chapter 3). |
|
缩写模式 Abbrev mode |
允许您使用单词缩写(第 3 章)。 Allows you to use word abbreviations (Chapter 3). |
|
段落缩进文本模式 Paragraph indent text mode |
用于缩进每个段落的第一行(第 7 章)。 For indenting the first line of each paragraph (Chapter 7). |
|
补充模式 Refill mode |
一种模式,Emacs 在编辑段落时尝试填充段落(有点实验性;在第 2 章中提到)。 A mode in which Emacs attempts to fill paragraphs as you edit them (a bit experimental; mentioned in Chapter 2). |
|
艺术家模式 Artist mode |
用于使用鼠标创建 ASCII 绘图(第 7 章)。 For creating ASCII drawings using the mouse (Chapter 7). |
|
轮廓模式 Outline mode |
用于撰写大纲(第 7 章)。 For writing outlines (Chapter 7). |
|
SGML名称实体模式 SGML name entity mode |
用于在 HTML、SGML 和 XML 文档中插入特殊字符(第 8 章)。 For inserting special characters in HTML, SGML, and XML documents (Chapter 8). |
|
ISO 重音模式 ISO accents mode |
用于在文本文件中插入重音字符。 For inserting accented characters in text files. |
|
字体锁定模式 Font lock mode |
用于以颜色和字体突出显示文本以提高可读性(例如,在视觉上将注释与代码分开)(第 9 章)。 For highlighting text in colors and fonts to improve readability (separating, for example, comments from code visually) (Chapter 9). |
|
编译模式 Compilation mode |
用于编译程序(第 9 章)。 For compiling programs (Chapter 9). |
|
丰富模式 Enriched mode |
用于保存文本属性(第10章)。 For saving text attributes (Chapter 10). |
|
VC模式 VC mode |
用于在 Emacs 下使用各种版本控制系统(第 12 章)。 For using various version control systems under Emacs (Chapter 12). |
|
信息模式 Info mode |
一种阅读 Emacs 自身文档的模式(第 14 章)。 A mode for reading Emacs's own documentation (Chapter 14). |
您可能已经注意到 段落缩进文本模式、大纲模式和编译模式等几种模式都是主要模式和次要模式。每个模式都可以单独使用——作为主要模式——或者与另一个主要模式作为次要模式。
You may have noticed that several modes, including paragraph indent text mode, outline mode, and compilation mode, are both major and minor modes. Each can be used alone—as a major mode—or with another major mode as a minor mode.
还有许多其他模式我们不会讨论,包括一些晦涩但有趣的编程语言(如 Modula-2)的模式。 Emacs 本身还使用一些其他模式,例如用于目录编辑功能的 Dired 模式(在第 5 章中描述)。
There are many other modes that we won't discuss, including modes for some obscure but interesting programming languages (like Modula-2). There are also some other modes that Emacs uses itself, like Dired mode for the directory editing feature (described in Chapter 5).
此外,如果您擅长 Lisp 编程,您可以添加自己的模式。 Emacs 几乎可以无限扩展。
In addition, if you're good at Lisp programming, you can add your own modes. Emacs is almost infinitely extensible.
要启动 Emacs, 只需单击 Emacs 图标或 在命令行中输入emacs并按 Enter 键即可。 [ 1 ]
To start Emacs, simply click on the Emacs icon or type emacs on the command line and press Enter.[1]
|
单击 Emacs 图标,或者从命令行键入:emacs Enter Click on the Emacs icon or, from the command line, type: emacs Enter |
|
|
|
启动 Emacs。 Starting Emacs. |
您将看到一条简短消息,描述一些重要的菜单项以及您正在运行的 Emacs 版本。它可能显示为图形启动屏幕(如此处所示)或文本启动屏幕。一旦您键入第一个字符,此消息就会消失。然后,Emacs 将您置于一个(几乎)空的缓冲区中,称为
*scratch*,这是您进行实验的理想场所。
You'll see a short message describing a few
important menu items and the version of Emacs that
you're running. It may appear as a graphical splash
screen (like the one shown here) or a text splash screen. This
message disappears as soon as you type the first character. Emacs
then puts you in an (almost) empty buffer called
*scratch*, an ideal place for you to experiment.
[ 1 ]启动 Emacs 的方式可能因平台而异。 Linux默认桌面上没有图标; Windows 和 Mac OS X 可以(如果您在这些平台上安装了 Emacs)。请注意,Mac OS X 附带安装在/usr/bin中的 GNU Emacs 版本 ,这是使用终端应用程序启动 Emacs 时默认运行的版本。如果您在终端应用程序中运行 Emacs,您将根本无法使用鼠标,并且还有许多其他限制。您可以使用更好版本的 GNU Emacs;详细信息请参见第 13 章。
[1] How you start Emacs may vary by platform. Linux has no icon on the desktop by default; Windows and Mac OS X do (if you've installed Emacs on these platforms). Note that Mac OS X comes with a version of GNU Emacs installed in /usr/bin, and that is what runs by default when you start up Emacs using the Terminal application. You won't be able to use the mouse at all if you run Emacs in the Terminal application, and there are a number of other limitations as well. Better versions of GNU Emacs are available to you; see Chapter 13 for details.
当你进入 Emacs,您会在窗口顶部附近看到一个大工作区,您可以在其中进行编辑。 (见图1-1。)
When you enter Emacs, you see a large workspace near the top of the window where you do your editing. (See Figure 1-1.)
光标标记您的位置。这 光标也称为点,特别是对于更熟悉 Emacs 和在线帮助系统的人来说;因此,记住这个术语很有用。
A cursor marks your position. The cursor is also called point, particularly among people who are more familiar with Emacs and in the online help system; therefore, it's useful to remember this term.
在开始打字之前,您无需执行任何特殊操作。只要您输入字母数字字符和标点符号,Emacs 就会将它们插入到缓冲区中。光标指示 Emacs 插入新字符的位置;它会随着您的打字而移动。与许多编辑器(尤其是vi)不同,Emacs 没有单独的插入文本和发出命令的模式。现在尝试输入一些内容,您就会开始发现 Emacs 是多么容易使用。 (如果您因任何原因卡住,只需按Cg即可。)
You don't have to do anything special before you start typing. As long as you type alphanumeric characters and punctuation, Emacs inserts them into your buffer. The cursor indicates where Emacs inserts the new characters; it moves as you type. Unlike many editors (particularly vi), Emacs does not have separate modes for inserting text and giving commands. Try typing something right now, and you'll begin to see how easy Emacs is to use. (If you get stuck for any reason, just press C-g.)
工具栏是一个新功能 在Emacs 21中,其基本图标及其功能如表1-3所示。请注意,工具栏是上下文相关的;在某些模式下,例如用于阅读 Emacs 手册的信息模式,工具栏会发生变化以提供浏览帮助。我们将讨论这些图标 当我们涵盖相关模式时。
The toolbar is a new feature in Emacs 21. Its basic icons and their functions are listed in Table 1-3. Note that the toolbar is context sensitive; in some modes, such as the Info mode for reading the Emacs manual, the toolbar changes to provide browsing help. We'll discuss those icons when we cover the relevant modes.
表 1-3。 Emacs 工具栏上的图标
Table 1-3. Icons on the Emacs toolbar
|
图标 Icon |
功能 Function |
哪里可以了解更多信息 Where to learn more |
|---|---|---|
|
|
查找文件或创建新文件(提供文件名)。 Find a file or create a new file (supplying the filename). |
本章 This chapter |
|
|
启动目录编辑器,以便您可以操作文件和文件夹。 Start the directory editor so you can manipulate files and folder. | |
|
|
杀死当前缓冲区。 Kill the current buffer. | |
|
|
将当前缓冲区保存在其关联文件中。 Save current buffer in its associated file. |
本章 This chapter |
|
|
将当前缓冲区保存为不同的文件。 Save current buffer as a different file. |
本章 This chapter |
|
|
撤消。 Undo. | |
|
|
剪切包含当前区域的文本。 Cut text that comprises the current region. | |
|
|
复制当前区域中的文本。 Copy text in current region. | |
|
|
粘贴剪切或复制的文本。 Paste cut or copied text. | |
|
|
搜索字符串。 Search for a string. | |
|
|
打印页面(带标题)。 Print page (with headings). | |
|
|
使用交互式界面进行定制。 Customize using interactive interface. | |
|
|
启动在线帮助系统。 Start online help system. |
如果您不喜欢工具栏,您可以 可以使用菜单选项(选项→显示/隐藏→ 工具栏)并选择选项→保存选项来隐藏它。有关详细信息,请参阅第 2 章末尾的第 2.7 节。
If you don't like the toolbar, you can hide it using a menu option (Options→ Show/Hide→ Toolbar), and choosing Options→ Save Options. For more information, see Section 2.7 at the end of Chapter 2.
菜单栏菜单列出选项“文件”、“编辑”、“选项”、“缓冲区”、“工具”和“帮助”;您可以探索它们以查看可用的选项。
The menu bar menu lists the options File, Edit, Options, Buffers, Tools, and Help; you can explore them to see what options are available.
除了导航之外 使用鼠标访问菜单,Emacs 现在提供弹出菜单。在Emacs窗口中,按住Ctrl并单击鼠标右键,弹出“编辑”菜单。[ 2 ]
In addition to navigating the menus using the mouse, Emacs now offers pop-up menus. In the Emacs window, hold down Ctrl and click the right mouse button to pop up the Edit menu.[2]
您无需访问菜单即可 使用键盘的鼠标。在这种情况下,使用键盘命令比菜单更有效,但为了完整起见,我们将向您展示如何使用基于文本的菜单。 (如果您更喜欢在 Emacs 中使用鼠标,但只能访问文本界面,请参阅第 13 章 ,了解如何下载和安装在 Unix、Linux、Mac OS X 或 Windows 上以图形方式运行的 Emacs 版本。)
You can access menus without a mouse using the keyboard. In this case, using keyboard commands is much more efficient than menus, but for completeness, we'll show you how to use the text-based menus. (If you prefer to use the mouse with Emacs but have access only to a text interface, see Chapter 13 to learn how to download and install a version of Emacs that runs graphically on Unix, Linux, Mac OS X, or Windows.)
如果您的鼠标无法使用菜单,请按F10或M-`(反引号,单左引号,位于 许多键盘左上角Tab键上方)来访问它们。
If your mouse does not work with the menus, press F10 or M-` (a back quote, the single open quotation mark, located above the Tab key in the upper-left corner of many keyboards) to access them.
|
按:F10 Press: F10 |
|
|
|
使用基于文本的菜单(Mac OS X 终端应用程序上的 Emacs 21.2)。 Using text-based menus (Emacs 21.2 on Mac OS X Terminal application). |
You can select text-based menu options in three ways:
您可以按Enter键选择迷你缓冲区中显示的默认选项。如果您想要其他选项,请按向上或向下箭头键,直到出现您需要的选项,然后按 Enter。
You can press Enter to select the default option that appears in the minibuffer. If you want a different one, press the up or down arrow key until the option you want appears and press Enter.
您可以在缓冲区中键入选项前面的字母
*Completions*。例如,键入f选择“文件”。
You can type the letter preceding the option in the
*Completions* buffer. For example, type f to choose File.
您可以按PgUp移动到
*Completions*缓冲区,然后使用箭头键移动到您想要的选项。按Enter 键。 (在 Mac OS X 上,请按Shift-PgUp。)
You can press PgUp to move to the
*Completions* buffer, then use the arrow keys to
move to the option you want. Press Enter. (On Mac OS X, press Shift-PgUp instead.)
选择菜单选项后,会出现该菜单的选项。重复该过程,直到找到您正在寻找的选项。
After you select a menu option, choices for that menu appear. Repeat the process until you find the option you're looking for.
就在上面在窗口底部(倒数第二行),Emacs 打印大量有关其正在执行的操作的信息。这条线称为模式线。在模式行的开头,您可能会看到有关 Emacs 用于该文件的编码系统的一些信息;通常您只会看到
--:,表明没有异常的编码方案。在模式线的左边缘附近,您可能会看到两个星号 ( **)。这些
星号表示您已经修改了正在编辑的内容。如果您没有进行任何更改,则星号不会出现。接下来,Emacs 打印缓冲区的名称
您正在编辑( *scratch*)。接下来,Emacs 会显示您在缓冲区中的位置 — 您相对于文件其余部分的位置以及您所在的行(图 1-1L5中的第 5 行)。如果您位于文件的开头,Emacs 会打印单词
;如果你到了最后,它会打印;如果您位于中间,它会显示百分比(例如,
表示您正在查看中点);如果整个文件可见,Emacs 将打印单词
。后面的括号中是您所处的编辑模式,在本例中是主要模式(没有处于活动状态的次要模式)。窗口一侧的滚动条还指示您在文件中的位置。[ 3 ]TopBot50%AllLisp
Interaction
Just above the
bottom of the window (on the second-to-last line), Emacs prints a lot
of information about what it's doing. This line is
called the mode line. At the beginning of the
mode line, you may see some information about the coding system that
Emacs is using for the file; usually you'll see just
--:, indicating that there is no unusual encoding
scheme in place. Near the left edge of the mode line, you may see two
asterisks (**). These
asterisks indicate that
you've modified whatever you're
editing. If you haven't made any changes, the
asterisks won't be there. Next, Emacs prints the
name of the buffer
you
are editing (*scratch*). Following this, Emacs
shows where you are in the buffer—your position relative to the
rest of the file and what line you are on (L5 for
line 5 in Figure 1-1). If you're
at the beginning of the file, Emacs prints the word
Top; if you're at the end, it
prints Bot; if you're in the
middle, it shows you a percentage (for example,
50% means you're looking at the
midpoint); and if the entire file is visible, Emacs prints the word
All. In parentheses following this is the editing
mode or modes you are in, in this case Lisp
Interaction is the major mode (no minor modes are active).
The scrollbar on the side of the window also indicates your position
in the file.[3]
您经常会同时使用多个缓冲区。在这种情况下,每个缓冲区都有自己的模式行,当您切换缓冲区时,模式行反映当前缓冲区的状态。现在不用担心这个;只需记住每个缓冲区都有一个模式行来描述它。
You will often work with several buffers simultaneously. In this case, each buffer has its own mode line, and when you switch buffers, the mode line reflects the state of the current buffer. Don't worry about this for now; just remember that every buffer has a mode line to describe it.
以下 模式行是迷你缓冲区。在此区域,Emacs 会回显您输入的命令,并在其中指定 Emacs 要查找的文件名、搜索和替换的值等。这也是 Emacs 显示错误消息的地方。如果您发现自己卡在迷你缓冲区中,请按Cg再次退出。
Below the mode line is the minibuffer. This is the area where Emacs echoes the commands you enter and where you specify filenames for Emacs to find, values for search and replace, and so on. It is also where Emacs displays error messages. If you find yourself stuck in the minibuffer, press C-g to get out again.
[ 2 ] Emacs 使用三键鼠标效果最佳(更多按钮也可以)。
[2] Emacs works best with a three-button mouse (more buttons are okay, too).
[ 3 ]滚动条的位置取决于您使用的平台和窗口系统。默认情况下,Linux 将滚动条放在左侧,而 Mac OS X 和 Windows 将滚动条放在右侧。另请注意,如果您在终端窗口中运行 Emacs,模式行中的信息顺序会有所不同。
[3] The scrollbar's location depends on the platform and windowing system you're using. Linux puts scrollbars on the left while Mac OS X and Windows put them on the right by default. Note also that the order of the information in the mode line is different if you run Emacs in a terminal window.
你即将开始 学习一些 Emacs 命令,所以让我们先讨论一下它们。你如何下达命令?每个命令都有一个正式的名称,(如果你很挑剔的话)它是一个 Lisp 例程的名称。有些命令名称很长;您通常不想输入整个内容。因此,我们需要某种方法来缩写命令。
You're about to start learning some Emacs commands, so let's discuss them a bit first. How do you give commands? Each command has a formal name, which (if you're fastidious) is the name of a Lisp routine. Some command names are quite long; you usually wouldn't want to type the whole thing. As a result, we need some way to abbreviate commands.
Emacs 将命令名称与短序列联系起来 的击键次数。这种命令与击键的联系是 称为 绑定。即使您通常不认为是命令的事情(例如插入您键入的字符)也是通过绑定机制处理的。像“A”这样的键绑定到 Emacs 命令 self-insert-command,该命令将它们插入到您正在编辑的缓冲区中。[ 4 ]您通常认为是编辑器命令的大多数操作都绑定到以 Ctrl或Meta开头的击键序列。 Emacs 还将一些命令绑定到鼠标单击(单独或通过Shift 或Ctrl修改)以及菜单上的选项。
Emacs ties a command name to a short sequence of keystrokes. This tying of commands to keystrokes is known as binding. Even things you don't normally think about as commands, such as inserting the characters that you type, are handled through the binding mechanism. Keys like "A" are bound to the Emacs command self-insert-command, which inserts them into the buffer you are editing.[4] Most actions that you would normally think of as editor commands are bound to keystroke sequences starting with Ctrl or Meta. Emacs also binds some commands to mouse clicks (alone or modified by Shift or Ctrl) and to options on menus.
Emacs 的作者尝试将最常用的命令绑定到最容易到达的按键序列。以下是您将遇到的各种按键序列:
The authors of Emacs try to bind the most frequently used commands to the key sequences that are the easiest to reach. Here are the varieties of key sequences you'll encounter:
这 最常用的命令(例如光标移动命令)绑定到C- n(其中 n是任意字符)。要按C- n,请按住 Ctrl键并按 n,然后松开这两个键。
The most commonly used commands (such as cursor movement commands) are bound to C- n (where n is any character). To press C- n, press and hold the Ctrl key and press n, then release both keys.
Slightly less commonly used commands are bound to M- n. To press M- n, press and hold the Meta key (usually next to the space bar), then press n.
其他常用的 命令绑定到Cx 某些内容(Cx后跟其他内容 - 一个或多个字符或另一个控制序列)。在其他类型的命令中,文件操作命令(就像您将要学习的命令一样)通常与Cx some绑定。
Other commonly used commands are bound to C-x something (C-x followed by something else—one or more characters or another control sequence). Among other types of commands, file manipulation commands, like the ones you are about to learn, are generally bound to C-x something.
一些 专门的命令必须 抄送 某些东西。这些命令通常与更专业的模式之一相关,例如 Java 模式或 HTML 模式。直到本书的后面部分你才会遇到它们。
Some specialized commands are bound to C-c something. These commands often relate to one of the more specialized modes, such as Java mode or HTML mode. You won't encounter them until later in this book.
这个列表仍然没有考虑到所有的可能性。您可以通过键入Mx long-command-name Enter来获取其余命令 。 (这确实适用于任何命令,但击键通常更容易学习。)
This list still doesn't take care of all the possibilities. You can get at the remaining commands by typing M-x long-command-name Enter. (This works for any command really, but the keystrokes are usually easier to learn.)
您可以定义自己的键绑定也是如此,如果您发现自己一直使用长形式的命令,则应该这样做。第 10 章将详细介绍该主题。
You can define your own key bindings, too, and you should do so if you find yourself using the long form of a command all the time. More on this topic in Chapter 10.
您还可以通过菜单访问常用命令,但为了最大程度地提高工作效率,我们建议您学习击键,这些击键通常在菜单选项后面的括号中给出。
You can also access common commands through menus, but for maximum productivity, we recommend you learn the keystrokes, often given in parentheses following the menu option.
[ 4 ]在某些特殊情况下编辑模式,例如用于查看和操作计算机上的目录的dired 模式,普通键入键不会自行插入。相反,它们绑定到执行打开和重命名文件等操作的特殊命令。这种定义和更改键盘映射的灵活性 ,虽然一开始看起来有些随意和难以承受,但却是 Emacs 的强大力量来源之一。
[4] In certain special editing modes, such as dired-mode for viewing and manipulating directories on your computer, the normal typing keys don't insert themselves. They are instead bound to special commands that do things like opening and renaming files. This flexibility in defining and changing keymaps, while it might seem somewhat arbitrary and overwhelming at first, is one of the great sources of power in Emacs.
您可以通过指定打开文件 从命令行或键入Cx Cf启动 Emacs 时的文件名 (长命令名称为find-file)。
You can open a file by specifying the filename when you start Emacs from the command line or by typing C-x C-f (the long command name is find-file).
工具栏上的纸张图标也运行此命令。在某些应用程序中,类似的图标只是创建一个新的未命名文件(例如,Document1在 Word 中)。 Emacs 希望您提供一个文件名,我们稍后会看到。
The paper icon on the toolbar also runs this command. In some
applications, a similar icon simply creates a new, unnamed file
(e.g., Document1 in Word). Emacs expects you to
provide a filename, as we'll see in a moment.
要按Cx Cf,请按住 Ctrl,按x,然后按f。现在释放Ctrl。
To press C-x C-f, hold down Ctrl, press x and then press f. Now release Ctrl.
按Cx Cf后,Emacs 使用迷你缓冲区询问您文件名。每当 Emacs 需要您输入时,它就会将光标放入迷你缓冲区中。在迷你缓冲区中输入完毕后,按Enter。
After you press C-x C-f, Emacs uses the minibuffer to ask you for the filename. Whenever Emacs wants input from you, it puts the cursor in the minibuffer. When you're done typing in the minibuffer, press Enter.
|
类型:输入 Type: |
|
|
|
Emacs 启动另一个缓冲区,其中包含新文件。 Emacs starts another buffer with the new file in it. |
如果您尝试读取同一个文件两次怎么办? Emacs 不会创建新的缓冲区,而是将您移动到文件所在的缓冲区。
What if you try to read the same file twice? Instead of creating a new buffer, Emacs just moves you to the buffer the file is in.
您还可以通过将文件拖放到 Emacs 窗口或 Emacs 图标上来在 Emacs 中打开文件。
You can also open a file in Emacs by dragging and dropping it on an Emacs window or on the Emacs icon.
如果您还没有尝试打字,现在是尝试打字的好时机。您可能会发现自己想要了解有关光标移动和编辑的更多信息;没关系。请随意浏览本章的其余部分并继续阅读第 2 章。我们建议您阅读有关保存文件和退出 Emacs 的部分。本章末尾还有一个命令表以供将来参考。如果您想了解有关使用文件以及一些快捷方式的更多信息,请继续阅读本章的其余部分。
Now is a good time to try typing if you haven't already done so. You may find yourself wanting to learn more about cursor movement and editing; that's fine. Feel free to skim the rest of this chapter and go on to Chapter 2. We recommend that you read the sections on saving files and exiting Emacs. There's also a table of commands at the end of this chapter for future reference. If you'd like to learn more about working with files as well as some shortcuts, stay with us through the rest of the chapter.
如果你碰巧读到 错误的文件,获取正确文件的一个简单方法是输入Cx Cv (用于find-alternate-file)。该命令的意思是“读取一个不同的文件,而不是我刚刚读取的文件”。输入Cx Cv后,Emacs 将当前文件的名称放入迷你缓冲区中;然后,您可以更正拼写错误或路径,这是查找错误文件的最常见原因。进行更正并按Enter。 Emacs 用备用文件替换缓冲区的内容。
If you happen to read the wrong file, an easy way to get the right file is by typing C-x C-v (for find-alternate-file). This command means "Read a different file instead of the one I just read." After typing C-x C-v, Emacs puts the name of the current file in the minibuffer; you can then correct a typo or the path, the most common reasons for finding the wrong file. Make the correction and press Enter. Emacs replaces the buffer's contents with the alternate file.
Emacs 有一个非常 称为完成的有用功能。如果您想要现有文件,则只需键入名称的前几个字母,足以唯一标识文件名。按 Tab 键,Emacs 会为您补全文件名。例如,假设您正在尝试查找名为dickens的文件。
Emacs has a very helpful feature known as completion. If you want an existing file, you need only type the first few letters of the name, enough to uniquely identify the filename. Press Tab, and Emacs completes the filename for you. For example, suppose you are trying to find a file called dickens.
|
类型:Cx Cf di Type: C-x C-f di |
|
|
|
Cx Cf之后,Emacs 会提示您输入文件名;输入前几个字母。 After C-x C-f, Emacs prompts you for the filename; type the first few letters. |
|
按:选项卡 Press: Tab |
|
|
|
当您按Tab时,Emacs 会填写文件名的其余部分。 When you press Tab, Emacs fills in the rest of the filename. |
如果多个文件以di开头,Emacs 将显示一个窗口,其中包含以该字符串开头的各种文件。您可以通过再输入几个字符(足以将您的文件标识为唯一)并 再次按Tab 键来选择一个。或者,您可以使用鼠标选择替代方案之一,或按PgUp移至完成窗口,移至所需选项,然后按 Enter。
If more than one file starts with di, Emacs displays a window with various files that start with that string. You select one by typing a few more characters (enough to identify your file as unique) and pressing Tab again. Or you can select one of the alternatives with the mouse or by pressing PgUp to move to the completions window, moving to the desired option, then pressing Enter.
完成也适用于长命令名称。这是一个很棒的 Emacs 功能,可以节省您的时间,并向您展示一些您可能不知道在此过程中存在的命令。第 14 章提供了有关完成的荣耀的更多细节。
Completion also works for long command names. It's a wonderful Emacs feature that can save you time—and show you some commands you might not know existed in the process. Chapter 14 provides more details on the glories of completion.
如果你 想要将一个文件插入到另一个文件中,只需移动到文件中的适当位置并输入Cx i 即可。 (是的,我们知道,我们还没有告诉您如何在文件中移动。现在使用箭头键,我们将在第 2 章中教您“真正的”Emacs 光标移动命令。) 追加文件,移动到文件末尾 ( M-> ) 并输入Cx i。与Cx Cf一样,Emacs 会提示您输入迷你缓冲区中的文件名。
If you want to insert one file into another, you simply move to the appropriate location in the file and type C-x i. (Yes, we know, we haven't told you how to move around in a file yet. Use the arrow keys for now and we'll teach you the "real" Emacs cursor movement commands in Chapter 2.) To append a file, move to the end of the file (M->) and type C-x i. As with C-x C-f, Emacs prompts you for the filename in the minibuffer.
什么时候 当您使用任何要求输入文件名的命令(例如Cx Cf)时,Emacs 会在迷你缓冲区中显示默认目录,并要求您输入文件名的其余部分。 Emacs 如何选择默认目录?默认目录取自光标当前所在的缓冲区。如果您在输入Cx Cf时正在编辑主目录中的文件,Emacs 会假定您要编辑主目录中的另一个文件。如果您正在编辑文件 /sources/macros/html.macs,则 Emacs 会创建默认目录/sources/macros。如果您想在其他目录中查找文件,请编辑 Emacs 显示的默认目录。
When you use any command that asks for a filename (such as C-x C-f), Emacs displays a default directory in the minibuffer and asks you to type the rest of the filename. How does Emacs choose the default directory? The default directory is taken from the buffer that the cursor is currently in. If you are editing a file in your home directory when you type C-x C-f, Emacs assumes you want to edit another file in your home directory. If you are editing the file /sources/macros/html.macs then Emacs makes the default directory /sources/macros. If you want to find a file in another directory, edit the default directory that Emacs displays.
为了保存
在您正在编辑的文件中,输入Cx Cs。 Emacs 写入文件。为了让您知道文件已保存,它会将消息“已写入文件名”放入迷你缓冲区中。如果您没有对文件进行任何更改,Emacs 会将消息放入No changes need to be saved迷你缓冲区中。您还可以通过按工具栏上的软盘或从“文件”菜单中选择“保存”(当前缓冲区)来访问此选项。
To save the
file
you are editing, type C-x C-s. Emacs
writes the file. To let you know that the file was saved, it puts the
message Wrote filename in the minibuffer. If you
haven't made any changes to the file, Emacs puts the
message No changes need to be saved in the
minibuffer. You can also get to this option by pressing the diskette
on the toolbar or choosing Save (current buffer) from the File menu.
*scratch*如果您决定通过键入Cx Cs来保存在缓冲区中输入的内容
,Emacs 会要求您输入文件名。给它一个文件名后,Emacs 会相应地更改模式行。
If you decide to save something you've typed in the
*scratch* buffer by typing C-x C-s, Emacs asks you for a filename. After
you give it a filename, Emacs changes the mode line accordingly.
相关命令是写入文件 (Cx Cw)。它相当于 Emacs 中的“另存为”选项,可在许多应用程序的“文件”中找到 菜单。write-file命令要求您在迷你缓冲区中键入新文件名。但是,如果您只是按 Enter键而不是键入新文件名,则write-file会使用旧名称保存文件,就像Cx Cs所做的那样。 (但是,它确实会询问您是否要将当前文件替换为该缓冲区中的文件。)
A related command is write-file (C-x C-w). It is the Emacs equivalent of the Save As option found on many applications' File menus. The write-file command asks you to type a new filename in the minibuffer. However, if you just press Enter instead of typing a new filename, write-file saves the file with its old name—just as C-x C-s would have done. (It does ask if you want to replace the current file with the one in this buffer, however.)
write-file命令对于编辑您无权更改的文件非常有用。使用 查找文件命令 将所需的文件放入缓冲区,然后使用write-file创建您自己的私有版本,并使用不同的名称或路径。此操作允许您将文件复制到您拥有且可以更改的文件中。当然,原始文件不受影响。
The write-file command is useful for editing files that you do not have permission to change. Use the find-file command to get the file you want into a buffer, and then use write-file to create your own private version, with a different name or path. This maneuver allows you to copy the file to one that you own and can change. Of course, the original file is not affected.
退出 Emacs,输入Cx Cc或像关闭任何其他应用程序一样关闭它。如果您对缓冲区进行了更改,Emacs 会询问您是否要保存它们。[ 5 ]如果您输入y,Emacs 会写入该文件,然后退出。如果您键入n ,Emacs 会要求您通过键入yes或no来确认是否要放弃所做的更改。如果您输入no,您的正常 Emacs 会话将继续,就像您从未尝试退出一样。如果输入yes,您将退出 Emacs,并且在此会话期间所做的更改不会永久生效。如果您进行了无意的更改,则离开而不保存更改可能会很有用 使.
To quit Emacs, type C-x C-c or close it like you would any other application. If you have made changes to a buffer, Emacs asks you if you want to save them.[5] If you type y, Emacs writes the file, then exits. If you type n, Emacs asks you to confirm that you want to abandon the changes you made by typing yes or no in full. If you type no, your normal Emacs session continues just as if you never attempted to exit. If you type yes, you exit Emacs and the changes you made during this session do not become permanent. Leaving without saving changes can be useful if you make changes you didn't intend to make.
顺便说一句,Emacs 对您输入y还是yes很挑剔。有时它想要一个,有时又想要另一个。如果它要求输入
y ,有时您可以输入yes来逃脱,但反之则不然。如果它发出蜂鸣声并显示 ,Please answer yes or no则您没有输入整个单词,而它希望您输入。
By the way, Emacs is picky about whether you type y or yes.
Sometimes it wants one, sometimes the other. If it asks for a
y, you can sometimes get away with
typing yes but not vice versa. If it
beeps and displays, Please answer yes or no, you
didn't enter the whole word and it wants you to.
[ 5 ]这一规则的一个例外是*scratch*缓冲区。可以这么说,它是一个便签本,Emacs 假设您在涂鸦,而不是在做严肃的艺术作品。如果您在缓冲区中做了任何重要的工作*scratch*,则必须显式保存它。
[5] One
exception to this rule is the *scratch* buffer.
It's a scratchpad and Emacs assumes you were
doodling, not doing serious artwork, so to speak. If you do any
serious work in the *scratch* buffer, you must
save it explicitly.
Emacs 拥有丰富的在线帮助,这将在第 14 章中进一步讨论 。您可以通过工具栏上的救星图标或通过“帮助”菜单输入帮助。两种方法都会向您显示帮助菜单, 本节稍后描述。要使用键盘输入帮助,请按 Ch。按Ch ?给你一个选项列表。按 Ch t会启动一个教程,这是对 Emacs 的精彩介绍。
Emacs has extensive online help, which is discussed further in Chapter 14. You can enter help through the lifesaver icon on the toolbar or through the Help menu. Either method will show you a help menu, described later in this section. To enter help using the keyboard, press C-h. Pressing C-h ? gives you a list of options. Pressing C-h t starts a tutorial that is an excellent introduction to Emacs.
要获取有关击键组合含义的信息,请按Ch k获取描述键。例如,如果您键入 Ch k Cx i ,Emacs 将显示insert-file命令的描述 ,该命令绑定到Cx i。按Ch f(表示“描述函数”)会要求 Emacs 描述一个函数(实际上只是一个命令名称,例如find-file)。本质上,Ch k和Ch f为您提供相同的信息;不同之处在于,使用Ch k时,您按下一个键,而使用Ch f时,您键入命令名称。
To get information about the meaning of a keystroke combination, press C-h k for describe-key. For example, if you type C-h k C-x i, Emacs displays a description of the insert-file command, which is bound to C-x i. Pressing C-h f (for describe-function) asks Emacs to describe a function (really just a command name, such as find-file). Essentially, C-h k and C-h f give you the same information; the difference is that with C-h k, you press a key whereas with C-h f, you type a command name.
假设您想了解Cx i的用途。
Assume you want to find out about what C-x i does.
需要注意的几件事:窗户
现在分为两部分,因为您正在查看两个单独的缓冲区。每个缓冲区都有自己的模式线。下层缓冲区为*Help*缓冲区;它包含有关插入文件命令的信息
。 Emacs 将光标保留在dickens
缓冲区中,因为没有充分的理由让您编辑缓冲区*Help*。
A few things to notice: the window
is
now split into two parts because you're looking at
two separate buffers. Each buffer has its own mode line. The lower
buffer is the *Help* buffer; it contains the
information about the insert-file
command. Emacs keeps the cursor in the dickens
buffer because there's no good reason for you to
edit the *Help* buffer.
您可能还注意到,在 描述该命令的文本,Emacs 称为光标 点。该术语在整个 Emacs 中都用来指代光标;你一定会遇到它。
You might also notice that in the text describing this command, Emacs calls the cursor point. This term is used throughout Emacs to refer to the cursor; you're bound to encounter it.
要使*Help*缓冲区消失,请按
Cx 1 (我们将在第 4 章中介绍此命令
)。
To make the *Help* buffer disappear, press
C-x 1 (we cover this command in
Chapter 4).
您还可以使用帮助菜单来访问帮助 快速命令,您可以通过菜单或工具栏上的救星到达那里。在此菜单上,您可以找到我们在此讨论过的选项:Emacs 教程、描述→描述键和描述→描述函数。它包含许多有趣的选项,包括访问 Emacs 常见问题 (FAQ) 文件、新的搜索功能,甚至还有 Emacs 精神病医生(您可能会告诉它“Emacs 今天让我崩溃了”)。有一个 Emacs 在线文档 Info 的接口。只需选择 Read the Emacs Manual 即可启动 Info.
You can also use the Help menu to access help commands quickly, and you can get there either through the menu or through the lifesaver on the toolbar. On this menu, you find options we've discussed here: Emacs Tutorial, Describe→ Describe Key, and Describe→ Describe Function. It includes a host of interesting options, including access to the Emacs frequently asked questions (FAQ) file, a new search feature, and even an Emacs psychiatrist (you might tell it something like "Emacs is driving me over the edge today"). There's an interface to Info, Emacs's online documentation. Simply choose Read the Emacs Manual to start Info.
在本节中,我们非常简要地介绍了您可以在帮助系统中采用的一些路径。还有更多的帮助设施;第 14 章对它们进行了详细描述 。我们在这里描述的帮助功能应该足以帮助您入门;如果您想了解更多信息,请跳至第 14 章。
In this section, we've given a very brief introduction to a few of the paths you can take in the help system. There are many more help facilities; they are described thoroughly in Chapter 14. The help features we've described here should be enough to get you started; if you want to learn more, jump ahead to Chapter 14.
现在您已经了解了启动和停止 Emacs 以及处理文件的基本命令。第 2 章建立在 这些命令为您提供使用 Emacs 进行编辑所需的技能。表 1-4 总结了本章介绍的命令。
Now you know the basic commands for starting and stopping Emacs and for working with files. Chapter 2 builds on these commands to give you the skills you need for editing with Emacs. Table 1-4 summarizes the commands we covered in this chapter.
表 1-4。文件处理命令
Table 1-4. File handling commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
Cx Cf 文件 → 打开文件 C-x C-f File → Open File |
查找文件 find-file |
找到文件并在新缓冲区中读取它。 Find file and read it in a new buffer. |
|
CXCv C-x C-v |
查找备用文件 find-alternate-file |
读取备用文件,用Cx Cf替换读取的文件。 Read an alternate file, replacing the one read with C-x C-f. |
|
Cx i文件→插入文件 C-x iFile → Insert File |
插入文件 insert-file |
在光标位置插入文件。 Insert file at cursor position. |
|
Cx Cs文件→保存(当前缓冲区) C-x C-sFile → Save (current buffer) |
保存缓冲区 save-buffer |
保存存档。 Save file. |
|
Cx Cw文件→将缓冲区另存为 C-x C-wFile → Save Buffer As |
写文件 write-file |
将缓冲区内容写入文件。 Write buffer contents to file. |
|
Cx Cc文件→退出 Emacs C-x C-cFile → Exit Emacs |
保存缓冲区-杀死-emacs save-buffers-kill-emacs |
退出 Emacs。 Exit Emacs. |
|
Ch C-h |
帮助命令 help-command |
进入在线帮助系统。 Enter the online help system. |
|
Ch f帮助→描述功能 C-h fHelp → Describe Function |
描述功能 describe-function |
提供给定命令名称的在线帮助。 Gives online help for a given command name. |
|
查看帮助→描述键 C-h kHelp → Describe Key |
描述键 describe-key |
提供给定击键序列的在线帮助。 Gives online help for a given keystroke sequence. |
|
Ch t帮助→ Emacs 教程 C-h tHelp → Emacs Tutorial |
教程帮助 help-with-tutorial |
开始 Emacs 教程。 Start the Emacs tutorial. |
|
Chi帮助→浏览手册 C-h iHelp → Browse Manuals |
信息转到 emacs 命令节点 info-goto-emacs-command-node |
启动 Start the |
Emacs 并不像本书所说的那样,也不像我们的屏幕截图那样。确保您有 GNU Emacs 21.3.5 或更高版本,通过输入Mx version Enter或选择帮助→关于 Emacs 来运行。阅读第 2 章中的“让 Emacs 按照您想要的方式工作”部分。如果您在终端窗口中运行,您可能需要安装图形版本的 Emacs;详细信息请参见第 13 章。
Emacs doesn't do what this book says or look like our screenshots. Make sure that you have GNU Emacs 21.3.5 or later running by typing M-x version Enter or selecting Help→ About Emacs. Read the section "Making Emacs Work the Way You Want" in Chapter 2. You may need to install a graphical version of Emacs if you are running in a terminal window; see Chapter 13 for details.
工具栏图标完全不同。 Emacs 21.3.1 和 Emacs 21.3.5 之间的图标发生了变化。年龄较大的 图标做同样的事情;较新的产品外观更好,也更直观。使用第 13 章中的说明升级 Emacs 。
The toolbar icons are completely different. The icons changed between Emacs 21.3.1 and Emacs 21.3.5. The older icons do the same thing; the newer ones are substantially better looking and more intuitive. Upgrade Emacs using instructions in Chapter 13.
您无法使用鼠标访问菜单。使用 通过按F10或M-`来代替基于文本的菜单。更好的是,按照第 13 章中的说明安装 Emacs 的图形版本。
You can't access menus using the mouse. Use the text-based menus instead by pressing F10 or M-`. Better yet, install a graphical version of Emacs using the instructions in Chapter 13.
PgUp无法正常工作 使用基于文本的菜单时。PgUp可能绑定到某些特定于应用程序的功能,例如在 Mac OS X 终端应用程序中滚动。按Shift-PgUp、F10或M-` 访问菜单。
PgUp doesn't work properly when using text-based menus. PgUp is probably bound to some application-specific function, such as scrolling in the Mac OS X Terminal application. Press Shift-PgUp, F10, or M-` to access the menus.
您看不到模式行或迷你缓冲区。你的 Emacs 窗口比显示器大。有关如何让 Emacs 以合理的窗口大小启动的信息,请参阅第 10 章。作为临时解决方法,请调整窗口大小。 (讽刺的是,在某些 Windows 系统上,最大化窗口会使其变小,从而解决问题。)
You can't see a mode line or minibuffer. Your Emacs window is bigger than your display. See Chapter 10 for information on how to get Emacs to start with a reasonable window size. As a temporary workaround, resize the window. (On some Windows systems, maximizing the window ironically makes it smaller, solving the problem.)
现在您已经了解了如何进入和退出 Emacs 以及使用文件的基础知识,是时候学习如何移动和编辑文件了。 Emacs 提供了多种在文件中移动的方法。起初,您可能会觉得很困惑,因为有这么多方法可以做同样的事情。要有耐心——随着你的学习,困惑会减少,你会开始欣赏 各种 Emacs 命令。您学习的方法越多,到达要编辑的文件部分所需的击键次数就越少。
Now that you know how to enter and exit Emacs as well as the basics of working with files, it's time to learn how to move around in and edit files. Emacs offers lots of ways to move around in files. At first, you might find it confusing that there are so many ways to do the same thing. Be patient—as you learn, the confusion will lessen, and you'll begin to appreciate the variety of Emacs commands. The more ways you learn, the fewer keystrokes you'll need to get to the part of the file you want to edit.
如果您想在阅读时练习命令(这将帮助您学得更快),请先从手边的任何内容中键入一两页;报纸很好。当您学习本章中描述的编辑技巧时,这将为您提供一些可以使用的文本。如果你犯了错误,不要担心;继续打字。在学习此处概述的基本编辑技巧后,您可以纠正任何错误。学习任何编辑器主要是形成某些手指习惯,而不是记住书上的内容。只有开始打字,您才能学会正确的手指习惯。
If you want to practice commands while you're reading—which will help you learn faster—start by typing a page or two from anything you happen to have handy; the newspaper is fine. That will give you some text to work with as you learn the editing skills described in this chapter. Don't worry if you make mistakes; just keep on typing. You can correct any mistakes after you learn the basic editing skills outlined here. Learning any editor is primarily a matter of forming certain finger habits rather than memorizing what the book says. You will learn the right finger habits only if you start typing.
当您打字并到达显示屏的右侧时,您有两个选择。您可以按Enter 键转到下一行,也可以继续输入。如果您键入一长行并且不按 Enter 键,Emacs 会一直等到您到达显示的末尾。然后,它会在该行的末尾放置一个弯曲箭头,并在下一行的开头放置一个弯曲箭头,作为视觉指示,表明下一行是上一行的延续(参见图 2-1)。如果 Emacs 在非图形环境中运行,则使用反斜杠 (\)。
When you are typing and you get to the right side of the display, you have two options. You can press Enter to go to the next line, or you can keep typing. If you type a long line and don't press Enter, Emacs waits until you reach the end of the display. Then it puts a curved arrow at the end of the line and one at the beginning of the next line as a visual indication that the next line is a continuation of the previous line (see Figure 2-1). If Emacs is run in a nongraphical environment, a backslash (\) is used instead.
图 2-1。 Emacs 的图形版本使用弯曲箭头来指示一条线是连续的;终端版本使用反斜杠
Figure 2-1. Graphical versions of Emacs use curved arrows to indicate that a line is continued; terminal versions use backslashes
补充模式是一种次要模式,
编辑段落时保持段落整洁。默认情况下它没有打开。查看模式线。如果出现该词Refill,则表明您已处于补充模式。如果没有,您只需输入Mx refill-mode Enter即可为此缓冲区打开它。如果您确定不喜欢重新填充模式,请再次键入Mx refill-mode Enter。该命令就像一个电灯开关:它打开和关闭重新填充模式。
Refill mode is a minor mode that
keeps
paragraphs neat as you edit them. It is not on by default. Look at
the mode line. If the word Refill appears, you are
in refill mode already. If not, you can turn it on for this buffer
only by typing M-x refill-mode
Enter. If you decide that you don't like
refill mode, type M-x refill-mode
Enter again. This command is like a light switch: it
toggles refill mode on and off.
您可能决定在编辑时自动进入补充模式。我们将在本章末尾描述如何执行此操作。
You may decide that you want to enter refill mode automatically whenever you edit. We'll describe how to do so at the end of this chapter.
在某些情况下,重新填充模式可能会很烦人,并且根据 Emacs 手册,它仍在进行中。你是
我更喜欢自动填充模式。您以同样的方式输入;输入Mx 自动填充模式 Enter。该词
Fill出现在模式行上。
In some contexts, refill mode can be annoying, and it is still a work
in progress according to the Emacs manual. You
m
ay
prefer auto-fill mode. You enter it in the same way; type M-x auto-fill-mode Enter. The word
Fill appears on the mode line.
当您键入段落时,自动填充模式会格式化它们。但是,当您编辑它们时,自动填充模式不会自动重新格式化它们。您可以使用fill-paragraph命令Mq自行完成此操作。
When you type paragraphs, auto-fill mode formats them. When you edit them, however, auto-fill mode does not automatically reformat them. You do that yourself using the fill-paragraph command, M-q.
如果您打开重新填充模式,然后决定使用自动填充模式,您仍然需要通过键入Mx refill-mode Enter显式关闭重新填充模式。否则,两种模式都会出现在模式行上,并且重新填充模式会继续其愉快的自动重新格式化段落,忽略自动填充模式已启用的事实。
If you turn on refill mode and then decide to use auto-fill mode, you still have to turn refill mode off explicitly by typing M-x refill-mode Enter. Otherwise, both modes appear on the mode line, and refill mode continues its merry automatic reformatting of paragraphs, ignoring the fact that auto-fill mode has been enabled.
重新格式化段落时要注意一个重要的陷阱。在文本模式下,段落是任何缩进或前后有空行的文本。如果您有一个没有空行的文件,Emacs 会认为它是一长段。输入Mq会获取所有文本,忽略换行符,并将其变成一长段。如果您有一个数据文件、一个程序,或者您只是更喜欢写入没有空行的文件,则此命令会遇到特殊问题。幸运的是,按C-_或Cx u (两者都用于撤消)可以神奇地将事情恢复原样。如果您经常创建没有空行的文件,这里有一些建议:
Watch out for one important pitfall when reformatting paragraphs. In text mode, a paragraph is any text that is indented or has a blank line before and after it. If you have a file with no blank lines, Emacs thinks it is all one long paragraph. Typing M-q takes all the text, ignoring line breaks, and makes it one long paragraph. This command is a particular problem if you have a data file, a program, or if you just prefer to write files with no blank lines. Luckily, pressing C-_ or C-x u (both for undo) magically puts things back the way they were. If you regularly create files with no blank lines, here are some suggestions:
而不是写作
在文本模式下,使用段落缩进文本模式。在此模式下,以任何空格开头的行都是一个新段落。输入Mx paragraph-indent-text-mode启动此模式;你会Parindent在模式行上看到。详细信息请参见第 6 章。
Instead of writing
in text mode, use paragraph indent
text mode. In this mode, a line that starts with any blank space is a
new paragraph. Type M-x
paragraph-indent-text-mode to start this mode;
you'll see Parindent on the mode
line. See Chapter 6 for more details.
使用特定模式而不是文本模式进行书写。例如,使用第 8 章中描述的 HTML 模式或 LaTeX 模式来编辑这些类型的文件。这些特殊模式重新定义了段落的含义,以便fill-paragraph命令正常工作。除此之外,这些模式与文本模式非常相似。
Use a specific mode rather than text mode for writing. For example, use HTML mode or LaTeX mode, described in Chapter 8, for editing files of these types. These special modes redefine what a paragraph means so that the fill-paragraph command works correctly. Otherwise, these modes are very similar to text mode.
不是填写一个段落,而是填写 称为区域的文本标记部分(我们将在本章后面讨论区域)。定义要填充的区域,然后按Mx fill-region Enter。此命令采用一个区域并格式化其中的每个单独段落。
Instead of filling a paragraph, fill a marked section of text called a region (we'll discuss regions later in this chapter). Define the region you want to fill and press M-x fill-region Enter. This command takes a region and formats each individual paragraph within it.
表 2-1列出了自动填充文本和使用自动填充重新格式化段落的命令 模式。
Table 2-1 lists commands for filling text automatically and reformatting paragraphs with auto-fill mode.
表 2-1。文本填充和重新格式化命令
Table 2-1. Text filling and reformatting commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
(无) [ 1 ] (none) [1] |
补充模式 refill-mode |
切换重新填充模式,在此模式下 Emacs 自动重新格式化文本。 Toggle refill mode, in which Emacs automatically reformats text. |
|
(无)选项 → 文本模式下的自动换行 (none)Options → Word Wrap in Text Modes |
自动填充模式 auto-fill-mode |
切换自动填充模式,在该模式下,Emacs 在您键入段落时格式化它们。 Toggle auto-fill mode, in which Emacs formats paragraphs as you type them. |
|
米q M-q |
填充段落 fill-paragraph |
重新格式化段落。 Reformat paragraph. |
|
(无)编辑 → 填充 (none)Edit → Fill |
填充区域 fill-region |
重新格式化区域内的各个段落。 Reformat individual paragraphs within a region. |
[ 1 ]请记住, 第一列中的(none)表示您在第二列中键入 Mx,后跟命令名称,然后按Enter 运行该命令。没有默认的击键。要使用 refill-mode命令,请键入Mx refill-mode Enter。 [1] Remember that (none) in the first column means that you type M-x followed by the command name in the second column, then press Enter to run the command. There are no default keystrokes. To use the refill-mode command, type M-x refill-mode Enter. | ||
移动光标的最简单方法 是单击鼠标左键或按箭头键。然而,一直拿鼠标很麻烦。学习使用键盘命令进行移动,这样您最终将在 Emacs 中实现令人眼花缭乱的速度和最大的生产力。
The easiest way to move the cursor is to click the left button on your mouse or to press the arrow keys. However, it's a hassle to reach for a mouse all the time. Learn to use keyboard commands to move around so that you will ultimately achieve blinding speed and maximum productivity in Emacs.
使用 Emacs 命令进行移动 将光标向前移动一格,输入 Cf(f表示“向前”)。正如您可能猜到的, Cb向后移动光标。要向上移动,请键入Cp(对于上一行),要向下移动,请键入 Cn(对于下一行)。如果您记住字母代表的含义,那么记住命令就会更容易。
To use Emacs commands to move the cursor forward one space, type C-f (f for "forward"). As you might guess, C-b moves the cursor backward. To move up, type C-p (for previous-line), and to move down, type C-n (for next-line). It's easier to memorize commands if you remember what the letters stand for.
图 2-2说明了如何使用 Emacs 命令进行上、下、左、右移动。
Figure 2-2 illustrates how to move up, down, left, and right using Emacs commands.
如果位于行尾,Cf会移动到下一行的第一个字符。同样,如果位于一行的开头,Cb会移动到上一行的最后一个字符。如果没有地方可去,Emacs 会发出蜂鸣声并显示消息Beginning of
buffer或End of buffer。
If you're at the end of a line, C-f moves to the first character on the next
line. Likewise, if you're at the beginning of a
line, C-b moves to the last
character of the previous line. If there's no place
to go, Emacs beeps and displays the message Beginning of
buffer or End of buffer.
现在我们将学习一些更高级的移动光标的方法。一种常见的方法是继续前进 向后移动一个单词:Mf向前移动一个单词; Mb向后移动 一个字。您还可以移至行首或行尾。Ca 将您移动到该行的开头(就像 a是字母表的开头一样)。Ce将您移至 该行的末尾。要向后移动一个句子,请输入Ma;要前进一个句子,请输入 Me。要一次前进一整段,请输入M-};要向后移动一个段落,请输入M-{。如果您位于句子或段落的中间,向后移动句子或段落实际上会将您带到当前句子或段落的开头。
Now we'll learn some more advanced ways to move the cursor. One common way is moving forward and backward by word: M-f moves forward a word; M-b moves backward a word. You can also move to the beginning or end of the line. C-a moves you to the beginning of the line (just like a is the beginning of the alphabet). C-e moves you to the end of the line. To move backward one sentence, type M-a; to move forward one sentence, type M-e. To move forward a whole paragraph at a time, type M-}; to move backward a paragraph, type M-{. If you're in the middle of a sentence or paragraph, moving back a sentence or paragraph actually takes you to the beginning of the current sentence or paragraph.
图 2-3使用维克多·雨果的《悲惨世界》中的几段来展示如何一次将光标移动多个字符。
Figure 2-3 uses a few paragraphs of Victor Hugo's Les Misérables to show how you can move the cursor more than one character at a time.
您可能已经在这里发现了一种模式。注意命令启动之间的区别 以 Ctrl和以Meta开头的 。Ctrl命令通常以比其关联的Meta命令更小的单位移动。例如,Cb将光标向后移动一个字符,而Mb 将光标向后移动一个单词。同样,Ca移动到行首,而Ma移动到句子开头。
You may have picked up on a pattern here. Notice the difference between commands starting with Ctrl and those starting with Meta. Ctrl commands generally move in smaller units than their associated Meta commands. For example, C-b moves the cursor backward one character, whereas M-b moves the cursor back one word. Likewise, C-a moves to the beginning of the line, whereas M-a moves to the beginning of a sentence.
关于搬家有一个注意事项 按句子或段落。 Emacs 非常严格地定义了一个句子。 除非在行尾,否则最后一个标点符号后需要两个空格。如果只有一个空格,Emacs 不会识别它。同样,按段落前后移动需要理解段落的 Emacs 定义。对于 Emacs(以及我们大多数人)来说,段落要么用制表符缩进,要么至少有一个空格,要么在段落之间有空行(块样式)。您可以更改这些定义,但首先您必须了解如何使用正则表达式,这将在第 3 章中进行简要讨论,并在第 11 章中进行更深入的讨论。第 10 章讨论如何更改变量。
There's one caveat about moving by sentence or paragraph. Emacs defines a sentence pretty strictly. You need two spaces after the final punctuation mark, unless you're at the end of the line. If there's only one space, Emacs won't recognize it. Similarly, moving backward and forward by paragraph involves understanding the Emacs definition of a paragraph. To Emacs (and to most of us), paragraphs are either indented with a tab or at least one space or have blank lines between them (block style). You can change these definitions, but first you have to understand how to use regular expressions, which are discussed briefly in Chapter 3 and in more depth in Chapter 11. Chapter 10 discusses how to change variables.
如果您的文件中有分页符,您可以通过键入Cx] (前页)或Cx[(后页)移至下一页或上一页。与段落和句子移动类似,逐页移动涉及 Emacs 对页面的定义。称为page-delimiter的变量定义了分页符的构成。如果文件中没有 Emacs 识别的分页符,Emacs 会将缓冲区视为一页很长的页面。在这种情况下, 前进页命令将您带到缓冲区的末尾,而向后页命令将您带到缓冲区的开头。
If your file has page breaks in it, you can move to the next page or previous page by typing C-x ] (forward-page) or C-x [ (backward-page). Similar to paragraph and sentence movement, moving by page involves the Emacs definition of what a page is. A variable called page-delimiter defines what constitutes a page break. If there are no Emacs-recognized page breaks in the file, Emacs regards the buffer as one very long page. In this case, the forward-page command takes you to the end of the buffer, and the backward-page command takes you to the beginning of the buffer.
在文本模式下,分页符是一个换页符,它告诉打印机在继续打印之前移至下一页(通过打印机送入下一个表格或页面,因此称为换页符)。如果您处于文本模式并且想要在文件中插入分页符,请键入Cq Cl(小写字母 L)。Cq是带引号的插入命令。它告诉 Emacs在文件中放置一个 Cl控制字符,而不是将Cl解释为 最近的命令。Cl字符看起来像两个字符 (^L),但实际上只有一个。 (尝试使用 Del删除一个,看看我们的意思。)
In text mode, a page break is a formfeed character that tells the printer to move to the next page (to feed the next form or page through the printer, hence the term formfeed) before continuing to print. If you are in text mode and you want to insert page breaks in your file, type C-q C-l (the lowercase letter L). C-q is the quoted-insert command. It tells Emacs to put a C-l control character in your file, rather than interpreting C-l as the recenter command. A C-l character looks like two characters (^L), but it's really only one. (Try to erase one using Del and see what we mean.)
与其他图形一样 应用程序中,您可以使用滚动条在 Emacs 中移动。与 Emacs 中的大多数操作一样,除了使用鼠标或滚动条移动之外,您还应该学习 Emacs 自己的键盘命令,以最大限度地提高您的工作效率。
Like other graphical applications, you can use the scrollbar to move around in Emacs. Like most things in Emacs, in addition to using the mouse or scrollbar to move around, you should learn Emacs's own keyboard commands to maximize your productivity.
如果您想一次一屏地翻阅文件,请使用 PgDown键或键入Cv。 Emacs 显示文件中的下一个全屏。它在顶部留下了上一屏幕中的几行内容,让您了解上下文。同样,按Mv(或PgUp键)将显示上一个屏幕。Mv和Cv一起提供了一种快速滚动文件的便捷方法。
If you want to page through a file one screen at a time, use the PgDown key or type C-v. Emacs displays the next full screen from your file. It leaves a couple of lines from the previous screen at the top to give you a sense of context. Likewise, pressing M-v (or the PgUp key) shows you the previous screen. Together, M-v and C-v provide a convenient way to scroll through a file quickly.
发生滚动 如果您键入任何超出当前显示文本限制的运动命令,则会自动执行此操作。例如,如果您在屏幕的最后一行并按Cn,Emacs 会向前滚动。同样,如果您位于屏幕顶部并按Cp,Emacs 会向后滚动。
Scrolling happens automatically if you type any motion command that takes you beyond the limits of the text currently displayed. For example, if you are on the last line of the screen and press C-n, Emacs scrolls forward. Similarly, if you are at the top of the screen and press C-p, Emacs scrolls backward.
你经常想移动所有到文件开头或结尾的路径。键入M->或按End 键转到缓冲区的末尾。要转到开头,请输入M-<或按 Home。它可能会帮助您记住 > 指向缓冲区的末尾,< 指向缓冲区的开头。
You often want to move all the way to the beginning or the end of a file. Type M-> or press End to go to the end of a buffer. To go to the beginning, type M-< or press Home. It may help you to remember that > points to the end of the buffer, and < points to the beginning of the buffer.
还有两种可能会派上用场的移动方式。 Mx goto-line Enter n Enter将光标移动到文件的第n行。当然,Emacs 从文件开头开始计算行数。同样,Mx goto-char Enter n Enter转到文件的第n个字符,从开头数起。在这两种情况下, n都是一个数字。
There are two more ways to move around that may come in handy. M-x goto-line Enter n Enter moves the cursor to line n of the file. Of course, Emacs starts counting lines from the beginning of the file. Likewise, M-x goto-char Enter n Enter goes to the nth character of the file, counting from the beginning. In both cases, n is a number.
对于程序员来说,这些命令很有用,因为许多编译器都会给出错误消息,例如Syntax error on line 356.通过使用这些命令,您可以轻松移动到错误位置。有一些更复杂的方法可以将 Emacs 与来自编译器和其他程序的错误报告链接起来。此外,其他几个光标移动命令仅在编辑程序时才适用(详细信息请参见第 9 章)。
For programmers, these commands are useful because many compilers
give error messages like Syntax error on line 356.
By using these commands, you can move easily to the location of your
error. There are some more sophisticated ways to link Emacs with
error reports from compilers and other programs. In addition, several
other cursor motion commands are applicable only when you are editing
programs (see Chapter 9 for details).
现在让我们学习一些效率 技巧。 Emacs 允许您根据需要多次重复任何命令。首先,您可以通过在命令前按M- n来重复命令任意次数 ,其中n是您要重复该命令的次数。该命令称为 数字 参数命令。
Now let's learn some efficiency tricks. Emacs lets you repeat any command as many times as you want to. First, you can repeat a command any number of times by pressing M- n before the command, where n is the number of times you want to repeat it. This command is called the digit-argument command.
如果你想让 M-n 多次重复该命令,你可以给M- n一个很大的参数。例如,假设您正在编辑一个 1000 行的大文件。如果您输入M-500 Cn,光标将向下移动 500 行,到达文件的中间点。如果您给M- n 一个比它可以执行的参数更大的参数,它会尽可能多次地重复该命令,然后停止。
You can give M- n a large argument if you want it to repeat the command many times. For example, let's say you are editing a large file of 1000 lines. If you typed M-500 C-n, the cursor would move down 500 lines, to the halfway point in the file. If you give M- n a larger argument than it can execute, it repeats the command as many times as possible and then stops.
您还可以使用另一个乘数命令: Cu(通用参数命令)。你可以 像给 M- n一样给Cu一个论证。键入M-5或Cu 5会重复后面的命令五次。但与 Mn 不同,Cu不需要参数来重复命令。如果没有参数,Cu将执行下一个命令四次。如果您输入Cu Cu,它会执行该命令 16 次。通过这种方式,您可以堆叠Cu以使命令执行多次:16、64、256 等。[ 2 ]
There's another multiplier command you can use, too: C-u (the universal-argument command). You can give C-u an argument just like you do M- n. Typing either M-5 or C-u 5 repeats the command that follows five times. But unlike M- n, C-u doesn't need an argument to repeat commands. With no argument, C-u executes the next command four times. If you type C-u C-u, it executes the command 16 times. In this way, you can stack up C-u's to make commands execute many times: 16, 64, 256, and so on.[2]
Cl,最近的命令,放置 当前行位于窗口的垂直中心。如果您在显示屏的底部或顶部键入,此功能非常有用。键入Cl可以快速将您关心的材料移动到显示屏的中间,这样可以更轻松地查看完整的上下文。
C-l, the recenter command, puts the current line in the center of the window vertically. This feature is useful if you're typing at the bottom or the top of the display. Typing C-l quickly moves the material that you care about to the middle of the display, where it is easier to see the full context.
如果由于某种原因显示内容被遮挡或包含随机字符, Cl还会重新绘制显示内容。这种情况不像我们使用终端时那样经常发生,但了解它可能是一件很方便的事情,特别是当您发现自己在终端界面中远程使用 Emacs 时。
C-l also redraws the display, if for any reason it appears obscured or contains random characters. This doesn't happen as often as it used to when we used terminals, but it can be a handy thing to know about, especially if you find yourself using Emacs remotely in a terminal interface.
表 2-2光标列表 移动命令。如果命令是助记符,则要记住的单词以斜体给出。
Table 2-2 lists cursor movement commands. If the command is mnemonic, the word to remember is given in italics.
表 2-2。光标移动命令
Table 2-2. Cursor movement commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CF C-f |
转发字符 forward-char |
向前移动一个字符(右)。 Move forward one character (right). |
|
镉 C-b |
向后字符 backward-char |
向后移动一个字符(左)。 Move backward one character (left). |
|
CP C-p |
上一行 previous-line |
移至上一行(向上)。 Move to previous line (up). |
|
中文 C-n |
下一行 next-line |
移至下一行(向下)。 Move to next line (down). |
|
MF M-f |
前向字 forward-word |
向前移动一个字。 Move one word forward. |
|
MB M-b |
后向词 backward-word |
向后移动一个字。 Move one word backward. |
|
钙 C-a |
行首 beginning-of-line |
移至行首。 Move to beginning of line. |
|
铈 C-e |
行结束 end-of-line |
移至行尾。 Move to end of line. |
|
我 M-e |
前句 forward-sentence |
向前推进一句话。 Move forward one sentence. |
|
嘛 M-a |
向后句 backward-sentence |
向后移动一句话。 Move backward one sentence. |
|
M-} M-} |
前段 forward-paragraph |
向前移动一段。 Move forward one paragraph. |
|
M-{ M-{ |
向后段落 backward-paragraph |
向后移动一段。 Move backward one paragraph. |
|
简历 C-v |
向上滑动 scroll-up |
向前移动一屏。 Move forward one screen. |
|
MV M-v |
向下滚动 scroll-down |
向后移动一屏。 Move backward one screen. |
|
] C-x ] |
前进页 forward-page |
向前移动一页。 Move forward one page. |
|
CX [ C-x [ |
向后翻页 backward-page |
向后移动一页。 Move backward one page. |
|
M-< M-< |
缓冲区开始 beginning-of-buffer |
移至文件开头。 Move to beginning of file. |
|
中号-> M-> |
缓冲区结束 end-of-buffer |
移至文件末尾。 Move to end of file. |
|
(没有任何) (none) |
转到行 goto-line |
转到文件的第n行。 Go to line n of file. |
|
(没有任何) (none) |
转到字符 goto-char |
转到文件的第n 个字符。 Go to character n of file. |
|
氯 C-l |
最近的 recenter |
重新绘制屏幕,当前行位于中心。 Redraw screen with current line in the center. |
|
M- n M- n |
数字参数 digit-argument |
重复下一个命令n次。 Repeat the next command n times. |
|
铜 C-u n |
普遍论证 universal-argument |
重复下一个命令n次(如果省略n则重复四次)。 Repeat the next command n times (four times if you omit n). |
您可以访问许多 Emacs 通过按键盘上的标准键来执行命令,例如PageDown(向下滚动一个屏幕)或Home(转到缓冲区的开头)。图 2-4显示了键盘布局示例以及按键的功能。您的密钥可能位于稍有不同的位置,但如果您有名称相同或相似的密钥,则应该可以使用。我们说“应该”是因为在某些情况下这些键不起作用 — 例如,如果您在远程计算机上使用 Emacs。我们建议您还学习标准 Emacs 命令;它们可以在任何键盘上使用,而且一旦你学会了它们,通常会更容易掌握。
You can access many Emacs commands by pressing standard keys on your keyboard, such as PageDown (to scroll down one screen) or Home (to go to the beginning of a buffer). Figure 2-4 shows a sample keyboard layout and what the keys do. Your keys may be in a slightly different place, but if you have a key with the same or a similar name, it should work. We say "should" because there are situations in which the keys won't work—for example, if you use Emacs on a remote machine. We recommend that you also learn the standard Emacs commands; they work on any keyboard, and they are often easier to reach once you learn them.
[ 2 ]最常见的是,您将使用我们在此描述的Cu 。然而,它并不总是起到乘数的作用。有时Cu会修改命令的功能。在本章后面,您将看到一个这样的案例。然而,如果你正在做一些乘数有意义的事情,那么Cu几乎肯定会起作用。
[2] Most often, you'll use C-u as we've described here. However, it doesn't always work as a multiplier; sometimes C-u modifies the command's function. Later in this chapter, you'll see one such case. However, if you're doing something where a multiplier makes sense, C-u is almost certain to work.
在开始练习删除之前 命令,您可能想知道撤消命令,本章稍后将详细讨论该命令。输入C-_或 Cx u会撤消上次编辑;再次输入 undo将撤消之前的编辑,依此类推。
Before you start practicing deletion commands, you might want to know the undo command, which is discussed fully later in this chapter. Typing C-_ or C-x u undoes your last edit; typing undo again undoes the edit before that one, and so on.
Emacs 提供了多种删除文本的方法。删除文本的最简单方法是按Del键,这会删除紧邻光标左侧的字符。请参阅 图 2-4了解键盘上Del键的可能位置。它有时被称为退格键。 Del最容易定义它的作用:它删除前一个字符。如果您在打字时决定删除您输入的最后一个字符,您会按哪个键?这就是 Emacs 称为 Del 的键。
Emacs provides many ways to delete text. The simplest way to delete text is to press the Del key, which deletes the character immediately to the left of the cursor. See Figure 2-4 for possible locations of the Del key on your keyboard. It is sometimes referred to as the Backspace key. Del is easiest to define by what it does: it deletes the previous character. If you're typing and you decide to erase the last character you typed, what key do you reach for? That's the key Emacs refers to as Del.
Emacs 提供了许多其他删除命令 — 也许对您来说太多了,尽管您最终会找到使用其中大部分命令的理由。例如,Cd(用于删除字符)删除光标下的字符。删除下一个单词的命令是Md(kill-word)。再次注意Meta键如何增强命令:Cd对字符进行操作,Md对单词进行操作。
Emacs provides a number of other deletion commands—perhaps too many for your taste, although you'll eventually find a reason to use most of them. For example, C-d (for delete-character) deletes the character under the cursor. The command for deleting the next word is M-d (for kill-word). Once again, note how the Meta key augments the command: C-d operates on a character, and M-d operates on a word.
Emacs有删除命令 下一个或上一个单词、句子和段落。当你在单词、句子或段落之间时,通过他们的名字,你可以猜出他们在做什么。然而,如果您位于一个实体的中间,它们会做一些有点令人惊讶的事情:它们会向后或向前删除当前单词、句子或段落的一部分,具体取决于命令是删除上一个还是下一个。例如,以下是Md根据光标所在位置的不同行为。
Emacs has commands to delete the next or previous word, sentence, and paragraph. By their names, you can guess what they do when you're between words, sentences, or paragraphs. If you're in the middle of an entity, however, they do something a little surprising: they delete a portion of the current word, sentence, or paragraph, backward or forward depending on whether the command deletes previous or next. For example, here's how M-d acts differently depending on where the cursor is.
同样,如果你在 一个单词的中间,并要求 Emacs 删除前一个单词(M-Del, forback-kill-word),它会从光标位置删除到当前单词的开头。
Similarly, if you are in the middle of a word and ask Emacs to delete the previous word (M-Del, for backward-kill-word), it deletes from the cursor position back to the beginning of the current word.
如果要删除整行或部分行,请使用命令Ck(代表kill-line)。该命令删除从光标到行尾的所有内容。在空行上键入Ck会删除该行本身。因此,通常需要两次Ck来删除一行:一次删除文本,一次删除生成的空行。如果您想删除从行首到光标处的所有内容,请尝试更复杂的咒语Meta - Ck(即按住Meta,后跟连字符,然后Ck)。
If you want to delete an entire line or part of a line, use the command C-k (for kill-line). This command deletes everything from the cursor to the end of the line. Typing C-k on a blank line deletes the line itself. So, it usually takes two C-k's to delete a line: one to delete the text and one to delete the resulting blank line. If you want to delete everything from the beginning of the line up to the cursor, try the more complex incantation Meta - C-k (i.e., hold down Meta, followed by a hyphen, and then C-k).
您还可以使用Ck连接两条线。如果您位于一行的末尾,Ck会删除换行符,从而有效地将两行变成一行长行。
You can also use C-k to join two lines. If you're at the end of a line, C-k deletes the newline character, effectively making two lines into one long line.
现在你可能已经注意到了 Emacs 中的一些删除命令称为kill命令,例如kill-region、kill-word等。在 Emacs 中,杀戮并不致命,但事实上恰恰相反。被杀死的文本并不会永远消失,而是隐藏在一个称为“ 杀死环”的区域中。杀戮环,虽然听起来有点像暴力团伙,但它是一个内部存储区域,Emacs 在这里放置您复制或删除的内容。不要将 Kill Ring 与系统剪贴板混淆,系统剪贴板允许在应用程序之间进行复制和粘贴。我们将在本章后面介绍 Emacs 与系统剪贴板的关系。
By now you may have noticed that some deletion commands in Emacs are called kill commands, such as kill-region, kill-word, and the like. In Emacs, killing is not fatal, but in fact, quite the opposite. Text that has been killed is not gone forever but is hidden in an area called the kill ring. The kill ring, though it sounds somewhat like a violent gang, is an internal storage area where Emacs puts things you've copied or deleted. Do not confuse the kill ring with the system clipboard, which allows for copying and pasting between applications. We'll cover how Emacs relates to the system clipboard later in this chapter.
您可以通过输入Cy(代表yank )来取回已删除的内容 。[ 3 ]方便的是,如果您连续杀死几行,Emacs 会将它们收集到一个项目中,并将整个单元放入杀死环中;单个Cy命令即可恢复所有内容。在下面的示例中,我们将使用Ck四次来删除A Tale of Two Cities的前两行。 (记住:第一个Ck删除文本;第二个Ck删除剩余的空行。)然后我们将使用单个Cy将所有内容恢复。
You can get back what you've deleted by typing C-y (for yank).[3] Conveniently, if you kill several lines in succession, Emacs collects them into a single item and places the whole unit into the kill ring; a single C-y command will bring everything back. In the following example, we'll use C-k four times to delete the first two lines of A Tale of Two Cities. (Remember: the first C-k deletes the text; the second C-k deletes the remaining blank line.) Then we'll use a single C-y to bring everything back.
究竟发生了什么 进入杀戮环?除了使用Cw删除的所有内容以及使用Mw复制的所有内容(您很快就会学到的两个命令)之外,您使用Ck删除的所有内容都会进入 Kill Ring。您使用Md、M-Del及其亲属删除的单词、句子和段落也会进入删除环。此外,使用Cu后跟Del或Cd删除的文本将进入删除环。 Emacs 唯一不保存在 Kill Ring 中的是单个字符,用Del 或Cd删除。 (如果需要,您可以使用绑定到C- _和Cx u的撤消命令恢复此类删除。)
What exactly goes into the kill ring? Everything you delete with C-k in addition to everything you delete with C-w and everything you copy with M-w (two commands that you'll learn shortly) go into the kill ring. Words, sentences, and paragraphs that you delete with M-d, M-Del, and their relatives also go into the kill ring. In addition, text that you delete with C-u followed by either Del or C-d goes into the kill ring. About the only thing that Emacs doesn't save in the kill ring is single characters, deleted with Del or C-d. (If you need to, you can get this type of deletion back using the undo command, bound to both C- _ and C-x u.)
Emacs 在将内容放入 Kill Ring 方面很聪明:当它从一组删除中组装一大块文本时,它总是正确地组装文本。例如,您可以输入一些 Md,然后输入一些M-Del ,最后再输入几个Ck 。当您输入Cy时,Emacs 会按照正确的顺序抽出您已删除的所有文本。 。
Emacs is clever about what it puts into the kill ring: when it is assembling a big block of text from a group of deletions, it always assembles the text correctly. For example, you can type a few M-d's, followed by some M-Del's, with a couple of C-k's thrown in. When you type C-y, Emacs yanks all the text that you've deleted in the proper order.
但是,您必须注意一件事。一旦您发出任何不是终止命令的命令,Emacs 就会停止组装这些文本块。例如,如果您键入Ck ,然后使用Cd删除单个字符 ,然后键入另一个Ck,则您已经破坏了链条。 Emacs 不认为用Cd删除单个字符是一个“kill”命令;这只是删除,并没有存储。在这种情况下,您还没有创建一个终止命令链;你已经制作了两条链子。稍后,我们将了解如何恢复较早的被删除的文本。
However, there's one thing you have to watch out for. Emacs stops assembling these blocks of text as soon as you give any command that isn't a kill command. For example, if you type C-k, then delete a single character with C-d, then type another C-k, you've broken the chain. Emacs doesn't consider deletion of a single character with C-d a "kill" command; it's just a deletion and it isn't stored. In this case, you haven't made a single chain of kill commands; you've made two chains. Later, we'll see how to get the older killed text back.
表 2-3总结了以下命令 删除、删除和拉出文本,包括“编辑” 菜单中的选项。
Table 2-3 summarizes the commands for deleting, killing, and yanking text, including options from the Edit menu.
表 2-3。删除命令
Table 2-3. Deletion commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
光盘 C-d |
删除字符 delete-char |
删除光标下的字符。 Delete character under cursor. |
|
德尔 Del |
删除向后字符 delete-backward-char |
删除前一个字符。 Delete previous character. |
|
MD M-d |
杀戮词 kill-word |
删除下一个单词。 Delete next word. |
|
M-德尔 M-Del |
向后杀字 backward-kill-word |
删除前一个单词。 Delete previous word. |
|
肌酸 C-k |
杀戮线 kill-line |
删除从光标到行尾的内容。 Delete from cursor to end of line. |
|
MK M-k |
杀句 kill-sentence |
删除下一句。 Delete next sentence. |
|
CX德尔 C-x Del |
向后杀句 backward-kill-sentence |
删除前一句。 Delete previous sentence. |
|
CY C-y |
猛拉 yank |
恢复您删除的内容。 Restore what you've deleted. |
|
Cw 编辑 → 剪切 C-w Edit → Cut |
杀伤区 kill-region |
删除标记的区域(请参阅下一节)。 Delete a marked region (see next section). |
|
(没有任何) (none) |
终止段落 kill-paragraph |
删除下一段。 Delete next paragraph. |
|
(没有任何) (none) |
向后删除段落 backward-kill-paragraph |
删除前一段。 Delete previous paragraph. |
[ 3 ]如果您是 Linux 或 Windows 用户,您可能习惯按Cv粘贴到所有应用程序中。 Emacs 可以选择将其默认的粘贴、剪切和复制命令更改为熟悉的 Cv、Cx 和 Cc。有关详细信息,请参阅“让 Emacs 按照您想要的方式工作”。另外,对 正在学习 Emacs 的 vi用户发出一个快速警告: vi也使用术语 yank,但其含义几乎完全相反。不要让这让你感到困惑。
[3] You may be used to pressing C-v to paste in all applications if you are a Linux or Windows user. Emacs has options to change its default paste, cut, and copy commands to the familiar C-v, C-x, and C-c. See "Making Emacs Work the Way You Want" for details. Also, a quick warning to vi users who are learning Emacs: vi also uses the term yank, but its meaning is almost the exact opposite. Don't let this confuse you.
如果您想要的文本怎么办 删除只是一个短语?还是半段?或者几段?在 Emacs 中,您选择 文本通过定义一个称为区域的区域来实现。您可以使用鼠标或键盘来标记区域。鼠标发生的情况有点复杂,因此我们在本章稍后讨论系统剪贴板之后对其进行描述。
What if the text you want to delete is just a phrase? Or half a paragraph? Or several paragraphs? In Emacs, you select text by defining an area called a region. You can mark regions with the mouse or by using the keyboard. What happens with the mouse is a bit complicated, so we describe it later in this chapter, following our discussion of the system clipboard.
要使用键盘定义区域,您可以使用 称为标记的辅助指针。某些版本的 Emacs 在屏幕上显示该标记;不幸的是,在 GNU Emacs 中,该标记是不可见的。
To define a region using the keyboard, you use a secondary pointer called a mark. Some versions of Emacs display the mark on the screen; unfortunately, in GNU Emacs, the mark is invisible.
您可以通过按C-Space或 C-@在该区域的一端设置标记,然后将光标移动到另一端 该区域的末端。 (光标有时也称为点。然而,光标和点之间有一个微小但重要的区别。光标位于字符的顶部;在 Emacs 中,点实际上位于光标所在的字符之间正如我们所说,这种差异很小,但它可以帮助您直观地看到标记区域时光标应在的位置。)图 2-5说明了点、标记和区域。
You set the mark at one end of the region by pressing C-Space or C-@, then move the cursor to the other end of the region. (The cursor is sometimes also referred to as point. There is one minor but important difference between the cursor and the point, however. The cursor is on top of a character; in Emacs, the point is actually in between the character the cursor is on and the previous character. As we said, this difference is minor, but it helps you to visualize where the cursor should be when you mark a region.) Figure 2-5 illustrates point, mark, and region.
让我们标记一个样本区域。在此示例中,我们删除了短语“it was the bad of times”。首先,我们找到该短语的开头。然后我们设置标记,前进到乐句末尾,然后剪切。
Let's mark a sample region. In this example, we remove the phrase "it was the worst of times." First, we find the beginning of the phrase. Then we set the mark, move forward to the end of the phrase, and cut.
|
移动到“it”的开头并按C-Space。 Move to the beginning of "it" and press C-Space. |
|
|
|
设置标记;标记集出现在迷你缓冲区中。 Set the mark; Mark set appears in the minibuffer. |
转到“那是智慧的时代”中的“i”。因为该点实际上就在“i”之前,所以这个位置恰到好处。
Move to the "i" in "it was the age of wisdom." Because the point is really just before the "i," this placement will be just right.
|
移至“那是智慧的时代”中的“i” Move to the "i" in "it was the age of wisdom" |
|
|
|
该点位于要标记区域的末端。 The point is at the end of the region to be marked. |
现在该区域已被标记。如果该区域未突出显示,您需要在发出删除命令之前确保其标记正确。按Cx Cx(交换点和标记);该命令交换标记和点的位置。如果光标移动到您认为标记所在的位置,则该区域已正确标记。特别是因为您看不到该标记,所以 在删除区域之前使用Cx Cx检查其位置是一个好习惯。使用 Emacs 多年的人仍然忘记设置标记,然后进行删除,而不知道自己刚刚删除了什么。 (绑定到C-_和Cx u的撤消命令在这种情况下会派上用场。)
Now the region is marked. If the region is not highlighted, you'll want to make sure it is marked correctly before giving the delete command. Press C-x C-x (for exchange-point-and-mark); this command swaps the locations of the mark and the point. If the cursor moves to where you thought the mark was, the region is marked correctly. Especially because you can't see the mark, it's a good habit to check its location using C-x C-x before deleting a region. People who have used Emacs for years still forget to set the mark and then make a deletion without knowing what they've just deleted. (The undo command, bound to C-_ and C-x u, comes in handy in such a case.)
为了切割该区域, 按 Cw(用于终止区域)。 (工具栏上的剪刀图标也有效。)
To cut the region, press C-w (for kill-region). (The scissors icon on the toolbar also works.)
如果你不确定自己做什么 删除后,只需按C-_即可撤消。文本仍被标记,如果需要,您可以使用Cw再次删除它。要移动文本,请对其进行标记,按Cw剪切区域,然后将光标移动到要插入文本的位置,然后按 Cy。如果您将文本拉回到错误的位置,只需键入C-_即可撤消它,然后移动到您真正想要放置文本的位置,然后再次按Cy。
If you're not sure of what you deleted, just press C-_ to undo it. The text is still marked, and you can delete it again with C-w if you want to. To move text, mark it, press C-w to cut the region, then move the cursor to the place you want to insert the text, and press C-y. If you yank the text back into the wrong location, just type C-_ to undo it, then move to the place you really wanted to put the text, and press C-y again.
定义区域时,通常在一端设置标记,然后将光标移动到区域的另一端。在一些最常见的情况下,一些快捷方式很有帮助。来标记一个 段落,按Mh。这会在段落末尾设置标记,并自动将光标放置在开头。类似地,Cx h(用于 mark-whole-buffer)标记整个缓冲区;光标移至开头,标记置于末尾。最后,Cx Cp标记当前页面,如果处于文本模式,则页面由Cl字符定义 。当然,标记段落、页面或缓冲区通常只是某些其他操作的前奏,例如杀死(Cw)。
When you're defining a region, you normally set the mark at one end and then move the cursor to the other end of the region. A few shortcuts are helpful in some of the most common situations. To mark a paragraph, press M-h. This sets the mark at the end of the paragraph and places the cursor at the beginning automatically. Similarly, C-x h (for mark-whole-buffer) marks the entire buffer; the cursor goes to the beginning, and the mark is placed at the end. Finally, C-x C-p marks the current page, with pages being defined by the C-l character if you are in text mode. Of course, marking a paragraph, page, or buffer is usually only the prelude to some other operation, like killing (C-w).
要复制文本,请标记 区域,然后按Mw(用于Kill-ring-save;带有两张纸的工具栏图标也运行此命令)。将光标移动到要插入复制文本的位置,然后按Cy。复制文本与删除文本完全相同,只是 Emacs 不会删除任何内容。您复制的文本被放置在 Kill Ring 中,因此您可以使用Cy随时访问它。
To copy text, mark a region, then press M-w (for kill-ring-save; the toolbar icon with two pieces of paper also runs this command). Move the cursor to the place where you want to insert the copied text and press C-y. Copying text is exactly the same as killing it, except that Emacs doesn't delete anything. The text you have copied is placed in the kill ring, so you can use C-y to access it as often as you like.
Mw的优点之一是它适用于只读文件和缓冲区。例如,如果您想创建一个 Emacs 提示文件,您可以使用Mw将在线帮助中的一些文本复制到您的缓冲区之一。
One advantage to M-w is that it works on read-only files and buffers. For example, if you wanted to create a file of Emacs hints, you could use M-w to copy some text from online help into one of your buffers.
以下是一些常见删除任务的步骤。
Here are the steps for some common deletion tasks.
将光标移动到要删除的区域的开头。
Move the cursor to the beginning of the area you want to delete.
按C-空格键。 Emacs 显示消息Mark set。
Press C-Space. Emacs displays the message Mark set.
将光标移动到要删除的区域的末尾。
Move the cursor to the end of the region you want to delete.
标记要删除的区域。
Mark the region to be deleted.
按Cw删除该区域。
Press C-w to delete the region.
使用标记和删除区域的过程删除要移动的文本。
Delete the text you want to move using the procedures for marking and deleting a region.
将光标移动到要插入文本的位置。
Move the cursor where you want to insert the text.
按CY。 Emacs 插入您删除的文本。
Press C-y. Emacs inserts the text you deleted.
标记您要复制的区域。
Mark the region you want to copy.
按Mw复制文本。
Press M-w to copy the text.
将光标移动到要插入复制文本的位置,然后按 Cy。 Emacs 插入您复制的文本。
Move the cursor where you want to insert the copied text and press C-y. Emacs inserts the text you copied.
前面我们提到过 Kill Ring,一个临时存储区域,Emacs 在其中保存您删除的内容。到目前为止,我们假设你有兴趣复活你最近杀死的东西。然而,杀戮环的作用远不止于此。它实际上存储了您最近删除的 30 条内容。我们发现Cy恢复了您最近删除的文本。输入“我”会删除您刚刚拉出的文本,并从删除环中获取下一个最新文本。
Earlier we mentioned the kill ring, a temporary storage area in which Emacs saves the stuff you delete. So far, we've assumed that you're interested in resurrecting what you've most recently killed. However, the kill ring does a lot more. It actually stores your last 30 deletions. We've seen that C-y restores the text you deleted most recently. Typing M-y deletes the text you just yanked and gets the next most recent text from the kill ring.
这是它的工作原理。在表 2-4中,假设您刚刚删除了“最近”一词。 赛从杀戮环中检索到这些文字。当您按My时,Emacs 会摆脱“最新”并获取下一个从杀戮环进入(“倒数第二个”)。
Here's how it works. In Table 2-4, assume that you've just killed the words "most recent." C-y retrieves these words from the kill ring. When you press M-y, Emacs gets rid of "most recent" and gets the next entry from the kill ring ("second-last").
您可以继续输入My,连续检索更古老的删除内容,直到到达终止环的末尾(此时它循环回到最近终止的文本;这就是它被称为环的原因)。
You can keep on typing M-y, retrieving successively more ancient deletions, until you reach the end of the kill ring (at which point it cycles back to the most recently killed text; that's why it's called a ring).
默认情况下,三十个删除是一个不错的大小——比大多数程序提供的要大得多。但是,如果您愿意,您可以使用名为Kill-ring-max的变量来放大或缩小 Kill Ring 的大小。要进行实验,请输入命令:Mx set-variable Enter Kill-ring-max Enter new-value Enter(其中new-value是数字)。
Thirty deletions by default is a nice size—far more generous than most programs offer. But you can enlarge or reduce the size of the kill ring if you wish, using a variable called kill-ring-max. To experiment, give the command: M-x set-variable Enter kill-ring-max Enter new-value Enter (where new-value is a number).
使用菜单,您可以访问 以更直接的方式从 Kill Ring 中获取文本:选择“编辑” → “选择并粘贴”。将出现一个显示删除内容的菜单,最新的内容位于顶部。为了向您显示尽可能多的删除内容,窗口中的每一行代表一个单独的删除内容。因此,如果您删除了一个大区域,例如 500 行,您只能看到该删除的第一行的开头、省略号和删除的结尾。您的选择将粘贴到缓冲区中的光标位置。
Using the menus, you can access text from the kill ring in a more straightforward way: by choosing Edit→ Select and Paste. A menu showing deletions appears, with the most recent ones on top. To show you as many deletions as possible, each line in the window represents a separate deletion. So if you've killed a large region, say 500 lines, you see only the beginning of the first line of that deletion, ellipses, and the end of the deletion. Your selection is pasted into the buffer at the cursor position.
表 2-5总结了命令 与地区合作。
Table 2-5 summarizes commands for working with regions.
表 2-5。用于处理区域的命令
Table 2-5. Commands for working with regions
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
C-@或C- 空格 C-@ or C- Space |
设置标记命令 set-mark-command |
标记区域的开始(或结束)。 Mark the beginning (or end) of a region. |
|
CX CX C-x C-x |
交换点和标记 exchange-point-and-mark |
交换光标和标记的位置。 Exchange location of cursor and mark. |
|
连续波 C-w |
杀伤区 kill-region |
删除区域。 Delete the region. |
|
CY C-y |
猛拉 yank |
粘贴最近删除或复制的文本。 Paste most recently killed or copied text. |
|
分子量 M-w |
杀环保存 kill-ring-save |
复制该区域(以便可以使用Cy进行粘贴)。 Copy the region (so it can be pasted with C-y). |
|
姆赫 M-h |
标记段落 mark-paragraph |
标记段落。 Mark paragraph. |
|
CXCp C-x C-p |
标记页 mark-page |
标记页面。 Mark page. |
|
CXh C-x h |
标记整个缓冲区 mark-whole-buffer |
标记缓冲区。 Mark buffer. |
|
我的 M-y |
猛拉流行音乐 yank-pop |
Cy之后,粘贴之前的删除内容。 After C-y, pastes earlier deletion. |
Emacs 21 运行良好 使用剪贴板,尽管在某些情况下它仍然可能无法执行您想要的操作。让我们更详细地探讨一下这一点。
Emacs 21 plays well with the clipboard, though it still may not do what you want it to in some cases. Let's dig into this in a little more detail.
默认情况下,文本 使用工具栏上的图标或“编辑”菜单上的选项剪切或复制的内容将放置在剪贴板上,可供其他应用程序访问。
By default, text that you cut or copy using icons on the toolbar or options on the Edit menu is placed on the clipboard and is accessible to other applications.
不幸的是,Emacs 在这个问题上因平台而异。通常我们将特定于平台的问题留到第 13 章,但是剪切和粘贴是一项至关重要的操作,因此我们必须在这里描述其中的差异。
Unfortunately, Emacs diverges by platform on this issue. Normally we save platform-specific issues for Chapter 13, but cutting and pasting is such a vital operation that we must describe the differences here.
在 Windows 和 Mac OS X(但不在 Linux 上)上,您使用Cw或Mw剪切或复制的任何文本也会复制到剪贴板。
On Windows and Mac OS X (but not on Linux) any text you cut or copy using C-w or M-w is also copied to the clipboard.
在 Windows 和 Mac OS X 上,只需用鼠标选择文本即可将其放置在剪贴板上。 (这在 Linux 上不起作用。)。大多数应用程序要求您突出显示文本,然后发出复制命令。 Emacs 没有。表2-6 所示 这是如何在各种平台上运作的。
On Windows and Mac OS X, simply selecting text with the mouse places it on the clipboard. (This doesn't work on Linux.). Most applications require you to highlight text, then issue a copy command. Emacs doesn't. Table 2-6 shows how this works on various platforms.
表 2-6。用鼠标选择文本
Table 2-6. Selecting text with the mouse
要将文本发送到 Linux 上的剪贴板,请用鼠标选择它(或将其标记为区域),然后单击剪切或复制工具栏图标或菜单选项。您还可以在任何平台上使用表 2-7中列出的特定于剪贴板的命令。
To send text to the clipboard on Linux, select it with the mouse (or mark it as a region), then click on the cut or copy toolbar icon or menu option. You can also use the clipboard-specific commands listed in Table 2-7 on any platform.
正如我们提到的,在 在其他应用程序中,您通常通过选择文本然后发出复制命令来剪切和粘贴。然后如何将该文本粘贴到 Emacs 中?
As we mentioned, in other applications, you typically cut and paste by selecting text, then issuing a copy command. How do you then paste that text into Emacs?
毫不奇怪,工具栏上的粘贴图标和“编辑”菜单上的关联选项在大多数情况下都会执行此操作(请参阅表 2-7;Mac OS X 上的 Emacs 不适当地禁用该图标和选项;关联的命令名称Clipboard-yank然而,有效)。Cy也从剪贴板插入文本。此外,简单的鼠标手势适用于大多数平台:只需在 Emacs 窗口中单击鼠标中键或鼠标滚轮即可从剪贴板粘贴。这里需要注意的是,您必须拥有带有中键的鼠标。
Not surprisingly, the paste icon on the toolbar and the associated option on the Edit menu do this in most cases (see Table 2-7; Emacs on Mac OS X disables both the icon and the option inappropriately; the associated command name clipboard-yank works, however). C-y inserts text from the clipboard too. Additionally, an easy mouse gesture works on most platforms: simply click the middle mouse button or mouse wheel in the Emacs window to paste from the clipboard. The caveat here is that you must have a mouse with a middle button.
表 2-7。从剪贴板粘贴
Table 2-7. Pasting from the clipboard
|
Linux Linux |
视窗 Windows |
Mac OS X 图形化 Mac OS X graphical |
Mac OS X 终端 Mac OS X terminal | |
|---|---|---|---|---|
|
赛粘贴? C-y pastes? |
是的 yes |
是的 yes |
是的 yes |
没有[ 5 ] no[5] |
|
工具栏粘贴图标粘贴? Toolbar paste icon pastes? |
是的 yes |
是的 yes |
不 no |
不 no |
|
编辑→粘贴选项是否粘贴? Edit→ Paste option pastes? |
是的 yes |
是的 yes |
不 no |
不 no |
|
鼠标中键粘贴? Middle mouse button pastes? |
是的 yes |
是的 yes |
是的 yes |
不 no |
|
Mx 剪贴板粘贴? M-x clipboard-yank pastes? |
是的 yes |
是的 yes |
是的 yes |
不 no |
另一个问题是 切割和 粘贴就是编码。在 Emacs 中,编码是一个复杂的主题; Emacs 22 预计将提供完整的 Unicode 支持。此时,我们只能向您指出一个可以帮助您解决与剪切和粘贴相关的编码问题的变量:set-clipboard-coding-system。
Another issue with cutting and pasting is encoding. Encoding is a complex topic in Emacs; full Unicode support is slated for Emacs 22. At this point, we can only point you to a variable that may help you resolve cut-and-paste related encoding issues: set-clipboard-coding-system.
如果您对剪贴板感兴趣,您可能需要将 Emacs 的剪切和粘贴键更改为更通用的Cx、Cc和Cv。有关更多详细信息,请参阅本章后面的“让 Emacs 按照您想要的方式工作”。
If you're interested in the clipboard, you may want to change Emacs' keys for cutting and pasting to the more universal C-x, C-c, and C-v. See "Making Emacs Work the Way You Want" later in this chapter for more details.
表 2-8总结了与剪贴板相关的内容 命令。
Table 2-8 summarizes clipboard-related commands.
表 2-8。剪贴板命令
Table 2-8. Clipboard commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
(没有任何) (none) |
剪贴板终止区域 clipboard-kill-region |
剪切区域并将其放置在杀伤环和系统剪贴板上。 Cut region and place both in kill ring and on system clipboard. |
|
(没有任何) (none) |
剪贴板复制 clipboard-yank |
从剪贴板粘贴文本。 Paste text from clipboard. |
|
(没有任何) (none) |
剪贴板-杀死-环-保存 clipboard-kill-ring-save |
将文本复制到剪贴板。 Copy text to clipboard. |
现在您已经了解了编辑的基础知识(将光标移动到正确的位置、删除、复制和移动文本),您可以学习一些使编辑更容易的技巧。
Now that you've learned the basics of editing—moving the cursor to the right position, deleting, copying, and moving text—you can learn some tricks that make editing easier.
最常见的 拼写错误涉及两个字母的调换,大多数拼写错误在您输入后会立即被发现。按Ct可以调换两个字母,将它们按正确的顺序排列:
The most common typo involves the transposition of two letters, and most typos are noticed immediately after you make them. Pressing C-t transposes two letters, to put them in the right order:
要调换两个字母,请将光标放在要调换的两个字母中的第二个字母上。按CT。 (如果您经常调换字母,第 3 章中讨论的单词缩写模式 会自动清除拼写错误。)
To transpose two letters, put the cursor on the second of the two letters to be transposed. Press C-t. (If you often transpose letters, word abbreviation mode, discussed in Chapter 3, cleans up typos automatically.)
您还可以调换两个单词、行、段落或句子。要调换两个单词,请将光标放在两个单词之间,然后按 Mt。 Emacs 完成后,光标将跟随两个(调换的)单词中的第二个单词:
You can also transpose two words, lines, paragraphs, or sentences. To transpose two words, put the cursor between the two words and press M-t. After Emacs has finished, the cursor follows the second of the two (transposed) words:
有趣的是,Emacs 可以移动单词,但不能 标点。假设两个名字颠倒过来:
Interestingly, Emacs moves words, but not punctuation. Let's say that two names are reversed:
要转置两行,请将光标放在两行中的第二行的任意位置,然后按Cx Ct。 Emacs 将第二个移动到第一个之前:
To transpose two lines, put the cursor anywhere on the second of the two and press C-x C-t. Emacs moves the second before the first:
|
Cx Ct 之前 Before C-x C-t |
Cx Ct 之后 After C-x C-t |
|---|---|
第二行 second line |
第一行 first line
|
第一 行 f irst line |
第二行 second line
|
第三行 third line |
第三 行 t hird line |
表 2-9总结了转置 命令。
Table 2-9 summarizes the transposition commands.
表 2-9。换位命令
Table 2-9. Transposition commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CT C-t |
转置字符 transpose-chars |
调换两个字母。 Transpose two letters. |
|
公吨 M-t |
转置词 transpose-words |
调换两个词。 Transpose two words. |
|
CXCt C-x C-t |
转置线 transpose-lines |
转置两行。 Transpose two lines. |
|
(没有任何) (none) |
转置句子 transpose-sentences |
调换两个句子。 Transpose two sentences. |
|
(没有任何) (none) |
转置段落 transpose-paragraphs |
调换两个段落。 Transpose two paragraphs. |
大小写也有错误 常见且烦人的打字错误。 Emacs 有一些用于固定大小写的特殊命令。要大写任何单词的第一个字母,请将光标放在第一个字母上,然后按Mc。要将单词转为小写,请按 Ml。插入一句话 大写,按Mu。这里的键绑定是助记符:Meta后跟c表示大写,l表示小写,u表示大写。请注意,如果光标位于单词的中间,Emacs 仅执行从光标下的字符到单词末尾的操作。您可以轻松地使用Ml将单词的后半部分小写,等等。
Mistakes in capitalization are also common and annoying typing errors. Emacs has some special commands for fixing capitalization. To capitalize the first letter of any word, put the cursor on the first letter and press M-c. To put a word in lowercase, press M-l. To put a word in uppercase, press M-u. The key bindings here are mnemonic: Meta followed by c for capitalize, l for lowercase, and u for uppercase. Note that if the cursor is in the middle of a word, Emacs takes action only from the character under the cursor to the end of the word. You can easily use M-l to lowercase the second half of a word, and so on.
如果您发现刚刚键入的单词不正确,您可以使用以Meta-开头的相同命令 (按住Meta,后跟连字符)。这会在不移动光标的情况下更正前一个单词。如果光标位于单词的中间,则在命令之前使用Meta-会导致它作用于单词的第一部分(光标前面的部分),而不是光标后面的部分。
If you notice that the word you just typed is incorrect, you can use the same commands prefaced by Meta- (press and hold Meta followed by a hyphen). This corrects the previous word without moving the cursor. If the cursor is positioned in the middle of a word, using Meta- before a command causes it to work on the first part of the word (the part preceding the cursor), rather than the part following the cursor.
例如,以e开头:
abcd
fghij
For example, starting with
abcd
e
fghij
:
|
如果您按: If you press: |
你会得到: You'll get: |
|---|---|
|
元-u Meta - u |
abcdEFGHIJ abcdEFGHIJ |
|
元穆 Meta - M-u |
ABCD和fghijABCDefghij
|
|
麦克 M-c |
abcd 埃夫吉 abcdEfghij |
|
元-麦克 Meta - M-c |
Abcd和fghijAbcdefghij
|
表 2-10总结了 大写命令。
Table 2-10 summarizes the capitalization commands.
表 2-10。大写命令
Table 2-10. Capitalization commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
麦克 M-c |
大写单词 capitalize-word |
单词的第一个字母大写。 Capitalize first letter of word. |
|
亩 M-u |
大写单词 upcase-word |
大写单词。 Uppercase word. |
|
毫升 M-l |
小写单词 downcase-word |
小写单词。 Lowercase word. |
|
元-麦克 Meta - M-c |
否定论证;大写单词 negative-argument; capitalize-word |
将前一个单词大写。 Capitalize previous word. |
|
元穆 Meta - M-u |
否定论证;大写单词 negative-argument; upcase-word |
前一个单词大写。 Uppercase previous word. |
|
元-ML Meta - M-l |
否定论证;小写单词 negative-argument; downcase-word |
小写前一个单词。 Lowercase previous word. |
你可能习惯了 覆盖旧文本而不必删除它。以这种方式销毁一些非常糟糕的文本有一定的满足感。您也可以在 Emacs 中通过进入称为覆盖模式的次要模式来执行此操作。当您处于覆盖模式时,您键入的任何新文本都会擦除下面的文本。当您未处于覆盖模式时(即在普通 Emacs 中),您键入的任何新文本都会插入到光标位置,并且所有后续文本都会被推到右侧。 (其他软件可能将此称为插入模式;因为这是 GNU Emacs 通常的行为方式,所以这里没有名称。)
You may be used to typing over old text rather than having to delete it. There is a certain satisfaction in destroying some really bad text in this way. You can do this in Emacs, too, by entering a minor mode called overwrite mode. When you're in overwrite mode, any new text you type wipes out the text that's underneath. When you're not in overwrite mode (i.e., in normal Emacs), any new text you type is inserted at the cursor position and any subsequent text is pushed to the right. (Other software may refer to this as insert mode; because it is the way GNU Emacs normally behaves, it doesn't have a name here.)
要进入覆盖模式,请按Insert键。[ 6 ] Ovwrt 应出现在模式行上。如果这不起作用(或者如果您没有Insert键),请键入Mx overwrite-mode Enter。您可以通过 再次键入Mx overwrite-mode Enter 来关闭覆盖模式。使用 Emacs 的命令完成功能,只需输入 Mx ov并按Enter即可。这个唯一的字符串足以告诉 Emacs 您想要切换覆盖模式。完成是 Emacs 中最好的快捷方式之一,将在第 14 章中进一步讨论。
To enter overwrite mode, press the Insert key.[6] Ovwrt should appear on the mode line. If this doesn't work (or if you don't have an Insert key), type M-x overwrite-mode Enter. You can turn off overwrite mode by typing M-x overwrite-mode Enter again. Using Emacs's command completion, simply type M-x ov and press Enter. This is enough of a unique string to tell Emacs you want to toggle overwrite mode. Completion, one of the best shortcuts in Emacs, is discussed further in Chapter 14.
有时您会意外启动命令或改变主意。不用担心:使用 Emacs,您可以中途退出或撤消它。
Sometimes you start a command by accident or change your mind about it. Don't worry: with Emacs, you can quit in the middle or undo it.
当您想取消任何 正在执行的命令,请按Cg。命令区域中出现“退出”一词。当您被困在迷你缓冲区中并且并不真正打算去那里时,此命令很有帮助。根据您正在执行的操作,您可能需要按几次Cg 。
When you want to cancel any command that's in progress, press C-g. The word Quit appears in the command area. This command is helpful when you are stuck in the minibuffer and didn't really mean to go there. Depending on what you were doing, you may have to press C-g a few times.
如果你做了一个,会发生什么 编辑时出错?您可以通过按C-_或Cx u来撤消更改(用于撤消;方便的是,工具栏还有一个撤消图标,即一个向左弯曲的箭头)。通过反复输入undo,您可以逐渐回到错误之前的位置。[ 7 ]虽然撤消 命令非常强大,但经常保存文件(如果不是强制的话)仍然是一个好主意。我们通常在停止打字时保存一个文件——即使只是几秒钟。训练你的手指 在暂停时按Cx Cs ;这是一个需要养成的好习惯。
What happens if you make a mistake while you're editing? You can undo your changes by pressing C-_ or C-x u (for undo; conveniently, the toolbar also has an undo icon, a curved left arrow). By typing undo repeatedly, you can gradually work your way back to a point before your mistake.[7] Although the undo command is very powerful, saving your file frequently, if not compulsively, is nevertheless a good idea. We usually save a file whenever we stop typing—even if only for a few seconds. Train your fingers to press C-x C-s whenever you pause; it's a good habit to form.
如果您习惯于输入Cz进行撤消,则可以轻松更改 Emacs 的行为以符合您的习惯。有关 CUA 模式的信息,请参阅本章末尾的“让 Emacs 按照您想要的方式工作”。
If you're used to typing C-z to undo, you can easily change Emacs's behavior to match your habits. See "Making Emacs Work the Way You Want" at the end of this chapter for information on CUA mode.
如果您想在输入 undo后重做命令怎么办?没有正式的 重做命令,但您可以通过以下方式使用撤消。只需向任意方向移动光标,然后 再次输入C-_或Cx u 。 Emacs 重做您撤消的最后一个命令。您可以重复此操作以重做之前的撤消操作。
What if you'd like to redo a command after you type undo? There is no formal redo command, but you can use undo in the following way. Just move the cursor in any direction, and type C-_ or C-x u again. Emacs redoes the last command you undid. You can repeat it to redo previous undos.
尽管撤消是一个重要的命令,但如果要撤消大量更改,它可能会很慢。表 2-11总结了撤消更改的三种方法以及您可能想要使用它们的情况。
Although undo is an important command, it can be slow if you want to undo a large number of changes. Table 2-11 summarizes three methods for undoing changes and circumstances in which you might want to use them.
表 2-11。撤消更改的方法
Table 2-11. Methods for undoing changes
|
如果你: If you: |
使用这个命令: Use this command: |
|---|---|
|
不喜欢您最近所做的更改并希望一一撤消它们 Don't like the recent changes you've made and want to undo them one by one |
C-_ 或 C-x u(撤消) C-_ or C-x u (undo) |
|
想要撤消自上次保存文件以来所做的所有更改 Want to undo all changes made since you last saved the file |
Mx 恢复缓冲区 输入 M-x revert-buffer Enter |
|
想要返回到文件的早期版本(即您开始此编辑会话时的文件) Want to go back to an earlier version of the file (the file as it was when you started this editing session) |
Cx Cf 文件名 ~ 输入 Cx Cw 文件名 Enter C-x C-f filename ~ Enter C-x C-w filename Enter |
我们已经讨论过使用 undo撤消更改;接下来我们描述如何从文件恢复缓冲区以及如何返回到早期版本。
We've already talked about undoing changes with undo; next we describe how to revert a buffer from a file and how to go back to an earlier version.
如果撤消命令不是 很有用,还有另一种方法可以将文件恢复到较早的状态。如果要将文件恢复到存储在磁盘上的状态,请键入Mx revert-buffer Enter。 Emacs 提出以下问题:
If the undo command isn't useful, there's another way to restore a file to an earlier state. If you want to get the file back to the state that is stored on disk, type M-x revert-buffer Enter. Emacs asks the following question:
从文件恢复缓冲区filename? (是还是不是)Revert buffer from file filename? (yes or no)文件名是原始文件的名称。如果您想恢复文件, 请键入yes;如果您改变主意,请键入no 。 Emacs 将存储在磁盘上的文件复制到缓冲区中,从而方便地忘记自上次保存文件以来发生的所有事情。尽管此命令称为 revert-buffer,但请注意,它只能恢复与文件关联的缓冲区。
The filename is the name of your original file. Type yes if you want to restore the file, or no if you've changed your mind. Emacs copies the file stored on disk into the buffer, conveniently forgetting everything that happened since the last time you saved the file. Although this command is called revert-buffer, note that it can revert only buffers associated with files.
第一次保存文件时 在编辑会话中,Emacs 会创建一个备份文件。如果发生灾难性的情况,并且其他撤消更改的技术无法帮助您,您可以随时返回到备份文件。这备份文件的名称与您正在编辑的文件的名称相同,并添加波浪号 ( ~ )。例如,如果您正在编辑文件text,则备份文件为 text~。
The first time you save a file during an editing session, Emacs creates a backup file. If something disastrous happens, and the other techniques for undoing changes won't help you, you can always return to the backup file. The name of the backup file is the same as the name of the file you're editing, with a tilde (~) added. For example, if you are editing the file text, the backup file is text~.
Emacs 不提供任何用于从备份副本恢复缓冲区的特殊命令。最简单的方法是编辑备份副本,然后将其另存为真实文件。例如,如果您正在使用名为 text的文件,您可以:通过键入Cx Cc退出 Emacs ,然后通过键入 emacs text~再次启动 Emacs 。显示备份文件后,输入Cx Cw 文本 Enter将其保存为真实文件。作为保护措施,Emacs 在覆盖原始文件之前会询问您:
Emacs doesn't provide any special commands for restoring a buffer from the backup copy. The easiest way to do this is to edit the backup copy and then save it as the real file. For example, if you were working with a file called text, you could: exit Emacs by typing C-x C-c, then start Emacs again by typing emacs text~. After the backup file is displayed, save it as the real file by typing C-x C-w text Enter. As a safeguard, Emacs asks you before it writes over the original file:
文件text已存在;覆盖? (y 或 n)File text exists; overwrite? (y or n)Type y to overwrite the original file with the backup file.
GNU Emacs 还有一个 编号备份设施。如果您打开编号备份,Emacs 会在 您每次保存文件时 创建一个备份文件(带有后缀~n~ )。 n随着每次连续保存而递增。如果您对删除旧版本感到紧张,那么它可能值得使用:如果您愿意,您可以永久保留所有旧版本。然而,编号备份也会浪费磁盘空间;一个好的办法可能是告诉 Emacs 保留最后n 个版本,其中n是您要保留的版本数。附录 A 中描述了控制编号备份的变量。如果您对成熟的版本控制感兴趣,请查看第 12 章中讨论的 VC 模式。表2-12 总结了用于停止命令和撤消更改的命令。
GNU Emacs also has a numbered backup facility. If you turn on numbered backups, Emacs creates a backup file (with the suffix ~n~) every time you save your file. n increments with each successive save. If you are nervous about deleting older versions, it might be worth using: you can keep all of your old versions forever, if you want to. However, numbered backups can also waste disk space; a happy medium may be to tell Emacs to keep the last n versions, where n is the number of versions you want to keep. The variables that control numbered backups are described in Appendix A. If you are interested in full-blown version control, check out VC mode, discussed in Chapter 12. Table 2-12 summarizes the commands for stopping commands and undoing changes.
表 2-12。停止和撤消命令
Table 2-12. Stopping and undoing commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
钙 C-g |
键盘退出 keyboard-quit |
中止当前命令。 Abort current command. |
|
CXu C-x u |
广告撤消[ 8 ] advertised-undo[8] |
撤消上次编辑(可以重复完成)。 Undo last edit (can be done repeatedly). |
|
C-_ 编辑 → 撤消 C-_ Edit → Undo |
撤消 undo |
撤消上次编辑(可以重复完成)。 Undo last edit (can be done repeatedly). |
|
(没有任何) (none) |
恢复缓冲区 revert-buffer |
将缓冲区恢复到文件上次保存(或自动保存)时的状态。 Restore buffer to the state it was in when the file was last saved (or auto-saved). |
我们刚刚讨论过如何 消除您不想保留的更改;找回丢失的更改是另一类问题。如果电源暂时断电或者您正在使用的计算机突然死机或意外关闭,您可能会丢失更改。如果异常退出 Emacs,您也可能会丢失更改。幸运的是,Emacs 作为一个细心的编辑器,经常会在自动保存文件中为您保存文件。如果你仔细观察,你会时不时地在迷你缓冲区中看到“自动保存”的消息。使用自动保存文件,您可以取回大部分(如果不是全部)更改。自动保存文件的名称与您正在编辑的文件的名称相同,但在开头和结尾添加一个尖号 ( # )。例如,如果您正在编辑文件 text,则其自动保存文件为 #text#。
We've just discussed how to eliminate changes you don't want to keep; getting back changes you've lost is a different kind of problem. You might lose changes if the power goes out momentarily or if the computer you're working on suddenly freezes or is turned off accidentally. You might also lose changes if you exit Emacs abnormally. Luckily, Emacs, being the watchful editor that it is, saves your file for you every so often in auto-save files. If you watch carefully, you'll see the message Auto saving in the minibuffer from time to time. Using auto-save files, you can get back most, if not all, of your changes. The name of an auto-save file is the same as the name of the file you are editing, with a sharp (#) added to the beginning and the end. For example, if you are editing the file text, its auto-save file is #text#.
要从 自动保存文件,输入Mx recovery-file Enter。 Emacs 打开一个窗口,其中列出了文件及其关联的自动保存文件,以便您可以比较它们的创建时间、大小等。 Emacs 会问你以下问题:
To recover text from an auto-save file, type M-x recover-file Enter. Emacs opens a window that lists both the file and its associated auto-save file so that you can compare the time at which they were created, their size, and so forth. Emacs asks you the following question:
恢复自动保存文件#text#? (是还是不是)Recover auto-save file #text#? (yes or no)输入yes确认您要将自动保存文件的内容复制到当前文件中, 如果您改变主意,则输入no 。 (如果您不确定,您可能需要先使用Cx Cf将自动保存文件#text#读 入缓冲区,然后在使用 恢复文件命令之前仔细查看它。如果您确实想比较两个版本,请参阅第 4 章中的“比较 Windows 之间的文件” 。)
Type yes to confirm that you want to copy the contents of the auto-save file into the current file or no if you change your mind. (If you are unsure, you might want to use C-x C-f to read the auto-save file #text# into a buffer first and look it over carefully before using the recover-file command. If you really want to compare the differences between the two versions, see "Comparing Files Between Windows" in Chapter 4.)
Emacs什么时候创建 自动保存文件?每几百次击键或者 Emacs 异常终止时,Emacs 就会创建一个自动保存文件。[ 9 ]您可以通过更改变量auto-save-interval 来更改 Emacs 创建自动保存文件的频率。默认情况下,Emacs 每 300 次按键创建一个自动保存文件。有关更改变量值的更多信息,请参阅第 10 章。
When does Emacs create auto-save files? Emacs creates an auto-save file every few hundred keystrokes or if Emacs is terminated abnormally.[9] You can change the frequency with which Emacs creates auto-save files by changing the variable auto-save-interval. By default, Emacs creates an auto-save file every 300 keystrokes. For more information on changing variable values, see Chapter 10.
关于 Emacs 和自动保存文件,还有一个更重要的事实需要了解。如果删除文件的大部分,Emacs 会停止自动保存文件并显示一条消息告诉您。要使 Emacs 再次开始自动保存,请使用Cx Cs保存文件或键入M-1 Mx auto-save Enter(即数字 1)。
There's one more important fact to know about Emacs and auto-save files. If you delete a large portion of a file, Emacs stops auto-saving the file and displays a message telling you so. To make Emacs start auto-saving again, save the file with C-x C-s or type M-1 M-x auto-save Enter (that's the number 1).
现在您已经学习了足够的命令来完成使用 Emacs 进行的大部分编辑。此时,您可能想了解如何让 Emacs 自动打开某些功能,例如自动填充模式,这样您就不必每次进入 Emacs 时都打开它们。下一节将简要介绍定制;第 10 章更详细地介绍了这个主题。
Now you've learned enough commands for most of the editing you'll do with Emacs. At this point, you may want to learn how to make Emacs turn on certain features like auto-fill mode automatically, so you don't have to turn them on every time you enter Emacs. The next section provides a brief introduction to customization; this topic is covered in much greater detail in Chapter 10.
[ 7 ]如果您发现经常重复撤消命令,那么熟练使用C-_是值得的。确实,这需要同时按住Ctrl和Shift,但是一旦按下,重复按_比一次又一次键入Cx u容易得多 。
[7] If you find that you repeat the undo command frequently, it's worth getting fluent with C-_. It's true that this requires holding down Ctrl and Shift at the same time, but once you've got that down, pressing _ repeatedly is much easier than typing C-x u again and again.
[ 9 ]应该说,Emacs试图做到这一点。在某些情况下,Emacs 不能,而且确实无法保证。电源浪涌和操作系统崩溃是事情发生得太快以至于 Emacs 可能无法创建自动保存文件的例子。但我们对它成功做到这一点的频率感到惊讶。
[9] We should say that Emacs tries to do this. In some cases, Emacs can't, and there is really no guarantee. Power surges and OS crashes are examples of times where things happen so fast that Emacs may not be able to create an auto-save file. But we are surprised at how often it manages to do so.
如果您一直在阅读这本书,您可能已经开始列出您想要更改的内容 关于 Emacs,例如
If you've been reading straight through this book, you may have started a list of things you'd like to change about Emacs, such as
隐藏工具栏
Hiding the toolbar
将 Emacs 剪切和粘贴命令更改为Cx、Cc和 Cv
Changing Emacs cut and paste commands to C-x, C-c, and C-v
打开文本模式和填充模式,以便 Emacs 进行自动换行
Turning on text mode and a fill mode so Emacs does word wrap
更改某些按键的工作方式
Changing the way some of the keys work
我们将告诉您如何为 Emacs 提供待办事项列表,即每次进入 Emacs 时打开的选项列表。这些选项在名为.emacs的初始化文件中定义 。初始化文件自动运行。有些在您启动计算机时运行。其他文件(例如 .emacs)会在您启动关联的软件程序时运行。因此,当您启动 Emacs 并打开文件定义的任何选项时,.emacs会自动运行。 Emacs 不需要这个文件来运行;它的唯一目的是让 Emacs 按照您希望的方式工作。
We're going to tell you how to give Emacs the to-do list, a list of options to turn on each time you enter Emacs. These options are defined in an initialization file called .emacs. Initialization files run automatically. Some run when you start up your computer. Others, like .emacs, run when you start up an associated software program. So .emacs runs automatically when you start Emacs and turns on whatever options the file defines. Emacs doesn't need this file to run; its only purpose is to make Emacs work the way you want it to.
.emacs文件由 Lisp 语句组成。如果您不是 Lisp 程序员,您可以将每一行视为遵循某种模式的咒语;你需要准确地输入它。
The .emacs file consists of Lisp statements. If you're not a Lisp programmer, you can think of each line as an incantation that follows a certain pattern; you need to type it exactly.
Emacs 现在有另一种处理定制的方法是:一个名为 Custom 的交互式界面,它为您编写 Lisp 并自动将其插入到您的.emacs文件中。自定义界面将在第 10 章中讨论,但我们将向您展示一种更快的常用选项方法。
Emacs now has another way to handle customization: an interactive interface called Custom that writes Lisp for you and automatically inserts it in your .emacs file. The Custom interface is discussed in Chapter 10, but we'll show you an even faster method for common options.
当您想直接向.emacs文件添加一行时,请执行以下步骤:
When you want to add a line to your .emacs file directly, take these steps:
输入 Emacs(如果您尚未进入)。
Enter Emacs (if you're not already there).
输入Cx Cf ~/.emacs Enter。
Type C-x C-f ~/.emacs Enter.
完全按照本书所示输入要添加的行,然后按 Enter 键。
Type the line to be added exactly as shown in this book and press Enter.
按Cx Cs保存 .emacs文件。
Press C-x C-s to save the .emacs file.
按Cx Cc退出 Emacs。
Press C-x C-c to exit Emacs.
重新启动 Emacs 以使该行生效。
Restart Emacs to have the line take effect.
如果您犯了一个小打字错误(例如忘记单引号或括号),您可能会Error in init file在重新启动 Emacs 时收到一条错误消息。只需再次编辑.emacs文件,检查您添加的行与获取它的位置(无论是来自本书还是其他用户的
.emacs文件)。通常,只要仔细观察就可以发现错误;如果没有,请找到拥有.emacs文件(并且最好了解 Lisp)的人
并寻求帮助。进行更改,保存文件,然后重新启动 Emacs。
If you make a minor typing mistake (such as forgetting a single
quotation mark or a parenthesis), you are likely to get an error
message that says Error in init file when you
restart Emacs. Simply edit the .emacs file
again, checking the line you added against the place you got it from,
whether from this book or another user's
.emacs file. Usually, you can find the error if
you look hard enough; if not, find someone who has a
.emacs file (and preferably understands Lisp)
and ask for help. Make the changes, save the file, and restart Emacs.
如果您所做的更改基本上导致 Emacs 无法启动怎么办?您仍然可以退出 Emacs,重命名文件,编辑它,然后另存为.emacs并重试。
What if you make a change that essentially keeps Emacs from being
able to start? You can still exit Emacs, rename the file, edit it,
then save it as .emacs and try again.
新用户可能会发现 工具栏很有帮助。其他人可能不会。通过选择选项→显示/隐藏→工具栏,然后选择选项→保存选项,可以轻松隐藏它。
New users may find the toolbar helpful. Others may not. It's easy to hide it by selecting Options→ Show/Hide→ Toolbar, and then Options→ Save Options.
当 Emacs 通过“自定义”为您设置选项时(即使您使用“选项”菜单,它也会这样做),它会写入您的 .emacs文件。如果您已有 .emacs文件,则会将其追加到该文件中。自定义本质上将其所有设置分组到文件的一个部分中,并对其进行注释以指示您不应手动更改它。这是我们通过选择此选项创建的.emacs文件:
When Emacs sets options for you through Custom (and this is what it is doing even when you use the Options menu), it writes your .emacs file. If you already have a .emacs file, it appends to it. Custom essentially groups all of its settings in one part of the file, and it is commented to indicate that you should not change it manually. Here's the .emacs file that we created by selecting this option:
(自定义设置变量 ;;自定义设置变量是由自定义添加的。 ;;如果您手动编辑它,可能会弄乱它,所以要小心。 ;;您的 init 文件应该只包含一个这样的实例。 ;;如果有多个,它们将无法正常工作。 '(工具栏模式 nil nil (工具栏))) (自定义设置面孔 ;;自定义设置面是由自定义添加的。 ;;如果您手动编辑它,可能会弄乱它,所以要小心。 ;;您的 init 文件应该只包含一个这样的实例。 ;;如果有多个,它们将无法正常工作。 )
(custom-set-variables ;; custom-set-variables was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. '(tool-bar-mode nil nil (tool-bar))) (custom-set-faces ;; custom-set-faces was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. )
这可能看起来有点庞大,但正如我们将在下一节中看到的,Emacs 仅添加此部分一次,然后当您通过选项菜单或直接通过自定义界面设置更多选项时会对其进行扩充。另请注意,这个自动生成的 Lisp 肯定不如您通常在.emacs文件中看到的 Lisp 语句干净。这是不直接编辑 Custom 作品的另一个原因。
This may seem a bit bulky, but as we'll see in the next section, Emacs adds this section only once and then augments it when you set more options either through the options menu or directly through the Custom interface. Also note that this auto-generated Lisp is certainly less clean than Lisp statements you'll typically see in .emacs files. That's another reason not to edit Custom's work directly.
如果您是 Emacs 新手, 您可能习惯于剪切、复制和粘贴的通用用户访问 (CUA) 约定,分别为Cx、Cc和Cv 。您可以使用Cz进行撤消。 CUA 模式曾经是一种必须单独安装的附加模式,但它变得非常流行,现在已成为 Emacs 的一部分。它的编码方式很巧妙,不会干扰以Cx和Cc为前缀的 Emacs 击键。有关 CUA 模式的详细信息请参见第 13 章。
If you're new to Emacs, you might be used to the Common User Access (CUA) conventions for cutting, copying, and pasting, C-x, C-c, and C-v respectively. You might reach for C-z for undo. CUA mode was once an add-on mode that you had to install separately, but it became so popular that it is now part of Emacs. It's coded in a clever way that doesn't interfere with Emacs keystrokes that are prefixed with C-x and C-c. Details on CUA mode can be found in Chapter 13.
您可以通过“选项”菜单打开此功能来尝试一下。只需选择选项→ Cx/Cc/Cv 剪切和粘贴 (CUA)。选择此选项后,“选项”菜单上该选项旁边会出现一个复选标记。要将其保留用于后续部分,请从“选项”菜单中选择“保存选项”。 Emacs 会为您编写.emacs 文件。如果您关闭工具栏然后设置此选项,您的.emacs文件将如下所示(请注意,与 CUA 模式相关的行是粗体,因此您可以看到与上一个示例的区别):
You can turn this feature on through the Options menu to try it out. Simply choose Options→ C-x/C-c/C-v cut and paste (CUA). After you select this option, a check mark appears next to it on the Options menu. To keep it for subsequent sections, select Save Options from the Options menu. Emacs writes your .emacs file for you. If you turned off the toolbar and then set this option, your .emacs file would look like this (note that the line relating to CUA mode is bold so you can see the difference from the previous example):
(自定义设置变量
;;自定义设置变量是由自定义添加的。
;;如果您手动编辑它,可能会弄乱它,所以要小心。
;;您的 init 文件应该只包含一个这样的实例。
;;如果有多个,它们将无法正常工作。
' (cua-mode t nil (cua-base))
'(工具栏模式 nil nil (工具栏)))
(自定义设置面孔
;;自定义设置面是由自定义添加的。
;;如果您手动编辑它,可能会弄乱它,所以要小心。
;;您的 init 文件应该只包含一个这样的实例。
;;如果有多个,它们将无法正常工作。
) (custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(cua-mode t nil (cua-base))
'(tool-bar-mode nil nil (tool-bar)))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
)有趣的是,Emacs 很高兴地写入.emacs 文件,即使它当时是打开的。如果您在选择“保存选项”时打开了文件,则可以看到 Emacs 更改该文件。
Interestingly, Emacs happily writes the .emacs file even if it is open at the time. You can watch Emacs change the file if you have it open when you choose Save Options.
将文本模式设置为默认模式 主要模式并在每次进入 Emacs 时自动启动自动填充模式,请将这些行添加到您的.emacs文件中:
To make text mode the default major mode and start auto-fill mode automatically each time you enter Emacs, add these lines to your .emacs file:
(setq 默认主要模式 '文本模式) (add-hook 'text-mode-hook '打开自动填充)
(setq default-major-mode 'text-mode) (add-hook 'text-mode-hook 'turn-on-auto-fill)
第一行告诉 Emacs 将文本模式设置为默认的主要模式;换句话说,“除非我另有说明,否则请打开文本模式。”每当您处于文本模式时,第二行都会打开自动填充模式。或者,选择“选项” → “文本模式自动换行”,然后选择“选项” → “保存选项”,将自动填充模式直接添加到您的.emacs 文件中。但是,它并不使文本模式成为默认的主要模式。
The first line tells Emacs to make text mode the default major mode; in other words, "Turn on text mode unless I tell you otherwise." The second line turns on auto-fill mode whenever you are in text mode. Alternatively, selecting Options→ Word Wrap in Text Modes, and then Options→ Save Options adds auto-fill mode to your .emacs file directly. It doesn't make text mode the default major mode, however.
如果您更喜欢重新填充模式,请将第二行代码替换为以下行:
If you prefer refill mode, replace the second line of code with this line:
(add-hook 'text-mode-hook (lambda ( ) (refill-mode 1)))
(add-hook 'text-mode-hook (lambda ( ) (refill-mode 1)))
.emacs文件的另一个主要用途是 重新定义 Emacs 中那些让你恼火的东西。您可能对 Emacs 的人体工程学有疑问;使用默认绑定时,不止一个人加重了腕管综合症。您可能只是习惯于按某些键来执行某些功能,并且宁愿改变 Emacs 而不是您的习惯。不管怎样,本节简要介绍了按键重新映射;详细信息请参见第 10 章。
Another major use of the .emacs file is to redefine things about Emacs that irritate you. You may have ergonomic concerns about Emacs; more than one person has aggravated carpal tunnel syndrome using the default bindings. You may simply be used to reaching for certain keys for certain functions and would rather change Emacs than your habits. Whatever the case, this section gives a brief introduction to key remapping; for more details, see Chapter 10.
如果您使用默认绑定(而不是 CUA 模式),则可以使用 Cx u进行撤消。[ 10 ] (撤消是一个非常常见的命令,当您重复撤消时,很容易错误地输入Cx Cu 。不幸的是, Cx Cu是upcase-region的禁用命令。如果您输入Cx Cu,则会出现一条关于启用该命令的恼人消息弹出。
If you use the default bindings (rather than CUA mode), you may use C-x u for undo.[10] (Undo is such a common command that it's easy to type C-x C-u by mistake when you undo repeatedly. Unfortunately, C-x C-u is a disabled command for upcase-region. If you type C-x C-u, an annoying message about enabling the command pops up.
如果您预计不会对升级区域有很大的需求,您可以重新定义Cx Cu,以便它也运行undo。为此,请将此行添加到您的.emacs文件中:
If you don't anticipate a big need for upcasing regions, you can redefine C-x C-u so that it also runs undo. To do so, add this line to your .emacs file:
(定义键全局映射“\Cx\Cu”'撤消)
(define-key global-map "\C-x\C-u" 'undo)
进行此更改后,输入Cx Cu会运行撤消操作,就像Cx u一样。
After making this change, typing C-x C-u runs undo, just as C-x u does.
Emacs 的定制功能非常强大,您可以让 Emacs 按照您想要的方式工作。第 10 章对定制进行了更广泛的处理。这个简短的介绍旨在激发您的兴趣,并使您能够向.emacs文件添加行,因为我们在整本书中提到了潜在的自定义。
Emacs customization is extremely powerful, and you can make Emacs work just the way you want it to. A far more extensive treatment of customization is found in Chapter 10. This brief introduction is meant to whet your appetite and to make it possible for you to add lines to your .emacs file as we mention potential customizations throughout the book.
下一章涵盖的主题包括 Emacs 提供的许多搜索,包括查询替换,以及拼写检查和单词缩写模式(通常用于自动纠正拼写错误)。如果您想了解这些功能,请继续下一章。从现在开始,你可以采取选择性的方式来阅读这本书,挑选你想了解的内容;您无需按顺序阅读本书的其余部分。
The next chapter covers topics such as the many searches offered by Emacs, including query-replace, as well as spell checking and word abbreviation mode (often used to correct typos automatically). If you want to learn about these features, go on to the next chapter. From here on, you can take a selective approach to reading this book, picking and choosing whatever you want to learn about; you don't need to read the rest of the book sequentially.
更改.emacs 文件后启动 Emacs 时,您会收到一条错误消息。该消息仅出现 简要地;按Mp再次查看。编辑您的 .emacs文件,根据源代码仔细检查您添加的行是否有轻微的印刷错误。像缺少连字符或撇号这样简单的事情都可能导致此错误。修复错误,保存文件,退出 Emacs,然后重新输入。在极端情况下(.emacs文件非常混乱,Emacs 甚至不允许您编辑它),退出 Emacs,重命名.emacs文件,然后启动 Emacs 并再次编辑它以修复它。将其重命名回 .emacs并重新开始。
You get an error message when you start Emacs after changing the .emacs file. The message appears only briefly; press M-p to view it again. Edit your .emacs file, checking the lines you added carefully against their source for minor typographical errors. Something as simple as a missing hyphen or apostrophe can cause this error. Fix the error, save the file, exit Emacs, and reenter. In extreme cases (the .emacs file is so messed up that Emacs won't even let you edit it), exit Emacs, rename the .emacs file, and then start Emacs and edit it again to fix it. Rename it back to .emacs and start again.
Paragraphs are not reformatted properly. This seems to relate to window size. Try resizing the window horizontally until paragraphs format properly.
[ 10 ]您可以使用C-_进行撤消,然后您就不需要阅读本节。我们建议您无论如何都阅读它,因为您可能会发现另一个想要更改的烦人的键映射,本节将介绍如何执行此操作。
[10] You could use C-_ for undo instead and then you wouldn't need to read this section. We recommend that you read it anyway because you might find another annoying key mapping that you want to change and this section tells a bit about how to do so.
我们在前两章中讨论的命令足以帮助您入门,但它们肯定不足以进行任何认真的编辑。如果您使用 Emacs 处理的内容超过几个段落,您将需要本章描述的支持。在本章中,我们将介绍 Emacs 允许您搜索和替换文本的各种方法。 Emacs 提供了您在任何编辑器中所期望的传统搜索和替换功能;它还提供了几个重要的变体,包括增量搜索、正则表达式搜索和查询替换。我们在这里还介绍了拼写检查,因为它是一种替换(查找错误并用更正替换)。最后,我们介绍一下单词缩写模式;此功能是一种自动替换,可以真正节省时间。
The commands we discussed in the first two chapters are enough to get you started, but they're certainly not enough to do any serious editing. If you're using Emacs for anything longer than a few paragraphs, you'll want the support this chapter describes. In this chapter, we cover the various ways that Emacs lets you search for and replace text. Emacs provides the traditional search and replace facilities you would expect in any editor; it also provides several important variants, including incremental searches, regular expression searches, and query-replace. We also cover spell-checking here, because it is a type of replacement (errors are sought and replaced with corrections). Finally, we cover word abbreviation mode; this feature is a type of automatic replacement that can be a real timesaver.
在编辑时,您经常想要查找已经输入的内容。几乎所有编辑器都提供某种搜索功能,让您查找特定的文本字符串,而不是在文件中寻找所需的内容。 Emacs 也不例外。它提供了一个搜索命令——事实上,它提供了一系列令人眼花缭乱的搜索命令。以下是可用的不同类型搜索的快速摘要:
While you're editing, you frequently want to find something you've already typed. Rather than hunt through the file trying to find what you're looking for, virtually all editors provide some kind of search feature that lets you look for a particular text string. Emacs is no exception to the rule. It supplies a search command—in fact, it provides a dizzying array of search commands. Here's a quick summary of the different kinds of searches that are available:
You give Emacs a search string, and it finds the next occurrence. You will find this search in almost any editor.
With incremental search, Emacs starts to search the file as soon as you type the first character of a search string. It continues to search as you type more characters.
单词搜索就像一个简单的搜索, 不同之处在于 Emacs 仅搜索完整的单词和短语。例如,如果您正在搜索单词hat,则不必担心找不到单词that。当您需要查找跨两行的短语时,单词搜索也很有用。
A word search is like a simple search, except that Emacs searches only for full words and phrases. For example, if you are searching for the word hat, you don't have to worry about finding the word that. A word search is also useful when you need to find a phrase that is spread across two lines.
要搜索模式,您可以 使用正则表达式搜索。例如,如果您想查找B1和B2的所有实例,您可以使用正则表达式B[12]搜索它们。然而,正则表达式可能非常复杂。我们在这里简单介绍一下这个话题;第 11 章对此进行了更全面的讨论。
To search for patterns, you can use a regular expression search. For example, if you wanted to find all instances of B1 and B2, you could search for them using the regular expression B[12]. However, regular expressions can be extremely complex. We'll give a brief introduction to this topic here; it is discussed more fully in Chapter 11.
This search procedure is a combination of an incremental search and a regular expression search.
您可以向前搜索或 落后。搜索可以区分大小写,这意味着 Emacs 认为大小写字母不同(即单词This 和this不同),也可以不区分大小写,其中不区分大小写(即 This和this )这是等价的)。默认情况下,搜索不区分大小写,大写和小写字母被视为相同。一个例外:如果您键入任何大写字母,Emacs 会使整个搜索字符串区分大小写;它假设您正在寻找精确的内容,因为您已经付出了额外的努力以大写字母输入一些字母。
You can search forward or backward. Searches can be either case-sensitive, meaning that Emacs considers upper- and lowercase letters to be different (i.e., the words This and this are different) or case-insensitive, in which upper- and lowercase are not differentiated (i.e., This and this are equivalent). By default, searches are case-insensitive, with upper- and lowercase letters considered to be the same. One exception: if you type any uppercase letters, Emacs makes the whole search string case-sensitive; it assumes you are looking for something precise since you've made the extra effort to type some letters in uppercase.
替换操作与搜索密切相关。与搜索一样,Emacs 为您提供了几种不同的风格:
Replacement operations are closely related to searches. As with searches, Emacs offers you several different flavors:
在此过程中,Emacs 替换 一个字符串与另一个字符串的所有出现。通常,这种解决方案过于激进,可能会产生意想不到的结果。请尝试查询替换。
In this procedure, Emacs replaces all occurrences of one string with another. Usually, this is too radical a solution and can have unintended results. Try query-replace instead.
使用查询替换,Emacs 有条件地替换整个文件中的字符串。 Emacs 查找所有出现的搜索字符串,并且对于每一个搜索字符串都会询问您是否执行替换。如果您需要更改整个文件中单词或短语的部分实例(而非全部实例),则这种类型的替换非常有用。
With query-replace, Emacs conditionally replaces a string throughout a file. Emacs finds all occurrences of the search string, and for each one it asks you whether or not to perform the replacement. This type of replacement is useful if you need to change some, but not all, instances of a word or phrase throughout a file.
Regular expression replacement uses the powerful pattern matching facility of the same name to find strings and replace them.
所以现在你知道你会看到什么了。不要被丰富的可用搜索吓倒。在实践中,您可能会选择一种搜索命令和一种替换命令,并在 99% 的工作中使用它们。例如,我们大多数时候使用增量搜索和查询替换。如果你是一名作家,你可能会一直使用单词搜索;如果您是程序员,您可能需要正则表达式搜索。如果您刚刚开始,您可能想学习增量搜索并稍后阅读本章的其余部分。但是,如果您知道可用的内容,则当其他搜索命令变得有用时,您将能够使用它们。
So now you know what you'll be looking at. Don't be intimidated by the wealth of searches that are available. In practice, you'll probably settle on one search command and one replace command and use these for 99 percent of your work. For example, we use incremental search and query-replace most of the time. If you're a writer, you may use word search all the time; if you're a programmer, you might want a regular expression search. If you're just beginning, you may want to learn incremental search and read the rest of this chapter later. However, if you know what's available, you'll be able to make use of the other search commands when they become useful.
增量搜索开始 从您键入搜索字符串的第一个字符的那一刻起就开始工作。许多用户喜欢增量搜索的效率,也喜欢突出显示。 Emacs 全部突出显示 搜索字符串的出现次数为水蓝色(如果您的显示器支持),并使用紫色突出显示光标位置处的字符串(当前匹配项)。
Incremental search starts to work from the moment you type the first character of the search string. Many users like the efficiency of incremental searches, and they like the highlighting as well. Emacs highlights all occurrences of the search string in aqua blue (if your display supports it) and uses purple to highlight the string at the cursor position (the current match).
开始增量
搜索,键入Cs,然后键入要查找的文本。 Emacs 暂时进入 Isearch 模式。请注意此搜索的工作原理:Emacs 在您键入每个字符后立即查找它。例如,如果您正在搜索单词
meter,则在增量搜索中,一旦您键入
m ,Emacs 就会找到下一个m;当你输入e时,它会立即找到下一个me;当您输入
t时,它会立即找到
met;等等。迟早,您要么找到您想要的东西,要么 Emacs 找不到任何东西。如果找到所需内容,请按Enter;这样做会停止在文件中当前位置的搜索。如果 Emacs 找不到任何与您的搜索字符串匹配的内容,它会在屏幕底部打印消息,然后发出蜂鸣声。Search failed
To start an incremental
search,
type C-s and then type the text you
want to find. Emacs temporarily enters Isearch mode. Notice how this
search works: Emacs looks for each character as soon as you type it.
For example, if you are searching for the word
meter, in an incremental search Emacs finds the
next m as soon as you type the
m; it finds the next me as
soon as you type the e; it finds the
met as soon as you type the
t; and so on. Sooner or later, you either find
what you want, or Emacs is unable to find anything. If you find what
you want, press Enter; doing so
stops the search at the current place in the file. If Emacs
can't find anything that matches your search string,
it prints the message Search failed at the bottom
of your screen and then it beeps.
这是当我们搜索单词 meter时发生的情况;数字显示光标如何随着搜索字符串中的每个新字母移动。
Here's what happens when we search for the word meter; the numbers show how the cursor moves with each new letter in the search string.
|
类型:Cs计 Type: C-s meter |
|
|
|
当您键入搜索字符串的字母时,Emacs 会将光标从一个位置移动到另一位置。 Emacs moves the cursor from one position to another as you type the letters of the search string. |
在此增量搜索中,当您键入搜索字符串meter时,Emacs 会将光标从位置1 移动到位置2、位置3,依此类推
。另请注意
Isearch模式行上出现的 。
In this incremental search, Emacs moves the cursor from position 1 to
2, to 3, and so on, as you type the search string
meter. Also, note that
Isearch appears on the mode line.
如果您找到了要查找的字符串,但没有找到该字符串的正确出现位置,会发生什么情况?假设您正在搜索“末世论”这个词并且找到了这个词,但您仍然没有找到正确的位置。只需再次按 Cs即可查找当前搜索字符串的下一个匹配项。 Emacs 使用相同的搜索字符串;您不必重新输入。
What happens if you find the string you're looking for but not the right occurrence of the string? Let's say you're searching for the word eschatology and you find the word, but you're still not in the right place. Simply press C-s again to find the next occurrence of the current search string. Emacs uses the same search string; you don't have to retype it.
找到所需文本后,请记住按Enter键。忘记停止搜索(通过按Enter或使用任何其他光标移动命令)是一个常见的错误:您输入了一些内容,然后 Emacs 突然开始查看文件中某个完全不同的部分。发生了什么事? Emacs 认为您仍在搜索,并且它刚刚将您键入的字符添加到搜索字符串中。
Remember to press Enter when you've found the text you want. Forgetting to stop the search (by pressing Enter or with any other cursor movement command) is a common mistake: you type a few things, and suddenly Emacs is off looking at some completely different part of the file. What has happened? Emacs thinks you're still searching, and it has just added the characters you've typed to the search string.
如果您在搜索字符串中输入的字母不正确,请按 Del:Emacs 返回到文件中缩减字符串的第一个实例。如果您继续按 Del 键从搜索字符串中删除字符,您将看到 Emacs 循环返回文件到先前的匹配项。
If you type a letter in your search string incorrectly, press Del: Emacs moves back to the first instance of the reduced string in the file. If you keep pressing Del to delete characters from the search string, you'll see Emacs cycle back through the file to previous matches.
要取消 搜索(即放弃搜索),输入Cg。此命令将带您返回到搜索开始的位置。
To cancel a search (that is, to give up searching), type C-g. This command brings you back to the place where the search began.
向后搜索通过文件,使用Cr ,其工作方式与Cs完全相同,只是它以相反的方向搜索。它将光标置于您找到的文本的开头。正如重复Cs时所做的那样,您可以按Cr使搜索向另一个方向进行,而无需重新键入搜索字符串。
To search backward through a file, use C-r, which works exactly like C-s except that it searches in the opposite direction. It puts the cursor at the beginning of the text you find. Just as you can do when repeating C-s, you can press C-r to make the search go in the other direction without retyping the search string.
为了避免输入搜索字符串,您可以将文本从缓冲区复制到搜索字符串中。复制文本来自 将光标位置通过下一个空格或标点符号插入搜索字符串,键入Cs Cw(将Cs Cw视为“搜索单词 ”可能会有所帮助)。要将文本从光标复制到行尾到搜索字符串中,请键入Cs Cy。请注意,被拉出的文本始终会转换为小写;此转换可确保搜索不区分大小写。您还可以通过键入Cs My将文本从 Kill Ring 复制到搜索字符串。发出此命令后,您可以按Mp查看杀戮环中的先前项目。如果您使用Mp返回,则Mn将带您前往下一个项目。
To avoid typing your search string, you can copy text from the buffer into the search string. To copy text from the cursor position through the next space or punctuation mark into the search string, type C-s C-w (it may help to think of C-s C-w as "search a word"). To copy text from the cursor to the end of the line into the search string, type C-s C-y. Notice that the text that is yanked is always converted to lowercase; this conversion ensures that the search will be case-insensitive. You can also copy text from the kill ring to the search string by typing C-s M-y. After you've given this command, you can press M-p to see previous items from the kill ring. M-n takes you to the next item if you've gone back with M-p.
一旦进行增量搜索,某些键(例如Enter和Del)就会具有与通常不同的功能。这种情况听起来可能令人困惑,但实际上很容易得到 习惯了。表 3-1 总结了增量搜索过程中的关键功能。
Once you're in an incremental search, certain keys (such as Enter and Del) have different functions than they normally do. This situation may sound confusing, but it's actually fairly easy to get used to. Table 3-1 shows a summary of key functions during incremental search.
表 3-1。增量搜索命令
Table 3-1. Incremental search commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
Cs 编辑 → 搜索 → 增量搜索 → 转发字符串 C-s Edit → Search → Incremental Search → Forward String |
isearch-forward isearch-forward |
开始向前增量搜索;接下来是搜索字符串。另外,查找搜索字符串的下一个出现(向前)。 Start incremental search forward; follow by search string. Also, find next occurrence (forward) of search string. |
|
Cr 编辑 → 搜索 → 增量搜索 → 向后字符串 C-r Edit → Search → Incremental Search → Backward String |
isearch-向后 isearch-backward |
开始向后增量搜索;接下来是搜索字符串。另外,查找搜索字符串的下一个出现(向后)。 Start incremental search backward; follow by search string. Also, find next occurrence (backward) of search string. |
|
进入 Enter |
isearch-退出 isearch-exit |
在增量搜索中,退出搜索。 In an incremental search , exit the search. |
|
钙 C-g |
键盘退出 keyboard-quit |
在增量搜索中,取消搜索。 In an incremental search , cancel the search. |
|
德尔 Del |
isearch 删除字符 isearch-delete-char |
在增量搜索中,从搜索字符串中删除字符。 In an incremental search, delete character from search string. |
|
铯CW C-s C-w |
isearch 拉取单词 isearch-yank-word |
使用光标所在的单词作为搜索字符串开始增量搜索。 Start an incremental search with the word the cursor is on as the search string. |
|
铯Cy C-s C-y |
isearch 拉线 isearch-yank-line |
使用从光标位置到行尾的文本作为搜索字符串开始增量搜索。 Start an incremental search with the text from the cursor position to the end of the line as the search string. |
|
我的铯 C-s M-y |
isearch-猛拉-杀死 isearch-yank-kill |
使用 Kill Ring 中的文本作为搜索字符串开始增量搜索。 Start an incremental search with text from the kill ring as the search string. |
|
铯 铯 C-s C-s |
isearch-重复-转发 isearch-repeat-forward |
重复之前的搜索。 Repeat previous search. |
|
铬 铬 C-r C-r |
isearch-向后重复 isearch-repeat-backward |
向后重复先前的搜索。 Repeat previous search backward. |
Emacs 还提供了一个简单的,或者 非增量,搜索。要使用更直接的搜索,请输入Cs Enter。输入搜索字符串,按Enter,Emacs 开始搜索。只需再次按Cs即可重复搜索。要在文件中开始向后非增量搜索,请按Cr Enter。再次输入搜索字符串并按Enter开始搜索。
Emacs also offers a simple, or nonincremental, search. To use a more straightforward search, type C-s Enter. Type the search string, press Enter, and Emacs begins the search. Simply press C-s again to repeat the search. To start a nonincremental search backwards through the file, press C-r Enter. Again, you type the search string and press Enter to begin the search.
上的搜索图标
工具栏(纸上的放大镜)和编辑→搜索→字符串转发选项运行相同类型的搜索。提示略有不同。Cs Enter在迷你缓冲区中提示您
Search:,而工具栏图标和菜单选项提示您Search for
string:。这是一个细微的差别;否则,搜索实际上是相同的。
The search icon on the
toolbar (a magnifying glass over paper)
and the Edit→ Search→ String Forward option run the
same kind of a search. The prompt is slightly different. C-s Enter prompts you with
Search: in the minibuffer while the toolbar icon
and the menu option prompt with Search for
string:. This is a minor difference; the searches are
virtually identical otherwise.
表 3-2总结了简单的 搜索命令。
Table 3-2 summarizes the simple search commands.
表 3-2。简单的搜索命令
Table 3-2. Simple search commands
|
击键 Keystrokes |
行动 Action |
|---|---|
|
Cs Enter Enter
编辑→搜索→字符串转发
C-s Enter
|
开始向前非增量搜索。 Start nonincremental search forward. |
|
CS C-s |
重复向前搜索。 Repeat search forward. |
|
Cr Enter
g Enter编辑→搜索→向后字符串
C-r Enter
|
向后开始非增量搜索。 Start nonincremental search backward. |
|
铬 C-r |
向后重复搜索。 Repeat search backward. |
如果您正在搜索一个短语并且 您知道它在文件中,但无法通过增量搜索找到它,请尝试单词搜索。 (您可能无法通过增量搜索找到您的短语,因为该短语中有换行符。)单词搜索是一种非增量搜索,它会忽略换行符、空格和标点符号。它还要求您的搜索字符串与文件中的整个单词匹配。
If you're searching for a phrase and you know it's in the file but you can't find it with incremental search, try word search. (You probably can't find your phrase with incremental search because the phrase has a line break in it.) Word search is a nonincremental search that ignores line breaks, spaces, and punctuation. It also requires that your search string match entire words in the file.
要进行单词搜索,请输入Cs Enter Cw(用于word-search-forward)。提示Word
search出现在迷你缓冲区中。 (不要被一路上出现的提示吓倒:I-search输入Cs后您会看到一个提示,按EnterSearch后您会看到一个
提示。忽略这些。)输入搜索字符串并按Enter。 Emacs 搜索给定的字符串。要向后进行单词搜索,请输入Cr Enter Cw。例如,假设您有以下文本,光标位于开头:
To do a word search, type C-s Enter
C-w (for word-search-forward). The prompt Word
search appears in the minibuffer. (Don't
be put off by the prompts that appear along the way:
you'll see an I-search prompt
after typing C-s and a
Search prompt after pressing Enter. Ignore these.) Type the search string
and press Enter. Emacs searches for
the given string. To do a word search backwards, type C-r Enter C-w instead. For example, assume
that you have the following text, with the cursor at the beginning:
他说:“所有优秀的大象都是聪明的,不是吗?” 她回答说:“有些人比其他人聪明,但我们 认为这是社会条件造成的。”
He said, "All good elephants are wise, aren't they?" She answered, "Some are smarter than others, but we think this is socially conditioned."
命令Cs Enter Cw They she Enter将光标定位在单词 She之后。这个命令看起来很复杂,但实际上无非是对单词 “they”进行单词搜索( Cs Enter Cw ) ,然后搜索单词“ she”。它忽略了他们和she之间的标点符号 (?") 和换行符 。
The command C-s Enter C-w they she Enter positions the cursor after the word She. This command looks complicated, but it's really nothing more than a word search (C-s Enter C-w) for the word they, followed by the word she. It ignores the punctuation (?") and the newline between they and she.
假设您正在查找单词 the。你不想理会then、there、 theatre、thesis、 blithe或任何其他恰好包含字母the 的单词。在这种情况下,增量搜索和简单搜索都没有多大用处——您需要单词搜索。如果您正在写论文,单词搜索通常正是您所需要的。它是三个基本搜索命令中唯一一个允许您找到所需内容的命令,即使短语分为两行。
Assume that you're looking for the word the. You don't want to bother with thence, there, theater, thesis, blithe, or any other word that happens to contain the letters the. In this situation, neither an incremental search nor a simple search is very useful—you need a word search. If you're writing a paper, word search is often exactly what you need. It is the only one of the three basic search commands that allows you to find what you want even if the phrase is split between two lines.
现在您已经了解了三种最常用的搜索,您可能想要尝试一下,看看哪一个最有用。
Now that you've seen the three most commonly used searches, you might want to experiment and see which you find most useful.
搜索和替换肯定是相辅相成的,就像咖啡和奶油一样。假设您正在开发一个新的软件应用程序,并且在最后一刻,营销部门决定更改产品的名称。
Search and replace definitely go together, like coffee and cream. Let's say you're working on a new software application and at the last possible moment, the Marketing Department decides to change the product's name.
这是 Whirligig 的新闻稿,这是一项电子邮件服务,定期提醒您改变健康的生活方式,例如锻炼、喝水和服用维生素。骚扰的程度,或者正如营销部门所说,鼓励的程度,可以由用户设定。 Whirligig 并不是真正最具描述性的名称,因此营销部门在最后一刻将其更改为 HealthBug。
Tere's a press release for Whirligig, an email service that periodically reminds you to make healthy lifestyle changes like exercising, drinking water, and taking vitamins. The level of harassment or, as the marketing department says, encouragement, can be set by the user. Whirligig isn't really the most descriptive name, so at the last minute the Marketing Department changes it to HealthBug.
假设你在我们刚才描述的情况。您希望将每个出现的一个字符串替换为另一个字符串。您知道 Whirligig 永远不会正确,并且对于您想要如何替换它绝对没有任何歧义。当您想要替换给定字符串的每个实例时,您可以使用一个简单的命令来告诉 Emacs 执行此操作。输入Mx Replace-string Enter,然后输入搜索字符串并按Enter。现在输入替换字符串并再次按Enter 键 。 Emacs 替换文件中从光标位置开始的所有匹配项。如果要在整个文件中搜索和替换,请在键入此命令之前按M-<转到文件开头。这是使用Replace-string的快速示例。
Assume you're in the situation we just described. You want to replace every occurrence of one string with another. You know that Whirligig is never correct, and there is absolutely no ambiguity about how you want to replace it. When you want to replace every instance of a given string, you can use a simple command that tells Emacs to do just that. Type M-x replace-string Enter, then type the search string and press Enter. Now type the replacement string and press Enter again. Emacs replaces all occurrences in the file from the cursor position onward. If you want to search and replace throughout the file, press M-< to go to the beginning of the file before typing this command. Here's a quick example of using replace-string.
|
初始状态: Initial state: |
|
|
|
Whirligig 出现四次,但光标位于第一个实例之后。 Whirligig appears four times, but the cursor is positioned after the first instance. |
现在我们将进行更换。
Now we'll do the replacement.
|
类型:Mx 替换字符串 输入 Whirligig 输入 HealthBug 输入 Type: M-x replace-string Enter Whirligig Enter HealthBug Enter |
|
|
|
Emacs 替换从光标位置开始的所有实例。 Emacs replaces all instances from the cursor position onward. |
替换仅从光标位置开始进行; 第一句中的Whirligig仍然不正确。稍后我们将再次使用这个示例。
The replacement occurs only from the cursor position onward; Whirligig in the first sentence is still incorrect. We'll work with this example again in a moment.
很少搜索和替换 情况就像我们所描述的那样简单。通常,您不确定是否要替换搜索字符串的所有外观:全局替换可能是鲁莽的。如果您想根据具体情况决定是否替换字符串,请使用查询替换,它允许您有条件地在整个文件中更改字符串。 Emacs 找到搜索字符串后,它会询问是否应该替换它,然后您做出相应的响应。
Few search and replace situations are as straightforward as those we've described. Often you're not sure that you want to replace every appearance of your search string: a global replacement can be reckless. If you want to decide whether to replace the string on a case-by-case basis, use a query-replace, which allows you to change a string conditionally throughout a file. After Emacs finds an occurrence of the search string, it asks whether it should replace it, and you respond accordingly.
要使用查询替换,请使用M-<转到缓冲区的开头
,然后键入M-%。提示符Query
replace:出现在迷你缓冲区中。输入搜索字符串并按Enter。现在出现了:
To use query-replace, go to the beginning of the buffer using
M-< and then type M-%. The prompt Query
replace: appears in the minibuffer. Type the search string
and press Enter. Now this appears:
查询替换searchstring 为:Query replace searchstring with:输入替换字符串并按Enter。到目前为止,这个过程几乎与替换字符串 操作相同;只是提示不同。
Type the replacement string and press Enter. So far, this procedure is almost identical to a replace-string operation; only the prompts are different.
Emacs 现在搜索搜索字符串的第一次出现。当找到一个时,会出现一个新提示:
Emacs now searches for the first occurrence of the search string. When it finds one, a new prompt appears:
查询替换searchstring为newstring
Query replacingsearchstringwithnewstring
在执行替换之前,Emacs 会等待响应来告诉它要做什么。表 3-3列出了可能的响应和 他们的结果。
Before performing the replacement, Emacs waits for a response to tell it what to do. Table 3-3 lists the possible responses and their results.
表 3-3。查询替换期间的响应
Table 3-3. Responses during query-replace
|
击键 Keystrokes |
行动 Action |
|---|---|
|
空格或y Space or y |
替换 Replace |
|
德尔或n Del or n |
不要更换;移至下一个实例。 Don't replace; move to next instance. |
|
。 . |
替换当前实例并退出。 Replace the current instance and quit. |
|
, , |
更换并让我看看结果,然后再继续。 (按 空格键或y 继续。) Replace and let me see the result before moving on. (Press Space or y to move on.) |
|
! ! |
剩下的全部换掉,别问。 Replace all the rest and don't ask. |
|
^ ^ |
备份到前一个实例。 Back up to the previous instance. |
|
输入或q Enter or q |
退出查询-替换。 Exit query-replace. |
|
乙 E |
修改替换字符串。 Modify the replacement string. |
|
铬 C-r |
输入递归编辑(稍后详细讨论)。 Enter a recursive edit (discussed in detail later). |
|
连续波 C-w |
删除此实例并输入递归编辑(以便您可以进行自定义替换)。 Delete this instance and enter a recursive edit (so you can make a custom replacement). |
|
CMc C-M-c |
退出递归编辑并恢复查询替换。 Exit recursive edit and resume query-replace. |
|
C-] C-] |
退出递归编辑并退出查询替换。 Exit recursive edit and exit query-replace. |
这个列表看起来需要记住很多击键,但是只要记住两三个就可以了。大多数时候,您将通过按 Space来响应提示,告诉 Emacs 执行替换并继续到下一个实例,或者n跳过此替换并继续到下一个实例。如果您不太确定会发生什么,请输入逗号 (,); Emacs 进行替换,但直到您按Space才会继续。执行前几次替换后,您可能会意识到没有必要单独检查每个更改。输入感叹号 ( ! ) 会告诉 Emacs 继续完成工作,不再打扰您。如果您记住了这些按键,则一切都已准备就绪。
This list seems like a lot of keystrokes to remember, but you can get away with knowing two or three. Most of the time you'll respond to the prompt by pressing Space, telling Emacs to perform the replacement and go on to the next instance, or n to skip this replacement and go on to the next instance. If you're not too sure what will happen, enter a comma (,); Emacs makes the replacement but doesn't go on until you press Space. After performing the first few replaces, you may realize that there's no need to inspect every change individually. Typing an exclamation mark (!) tells Emacs to go ahead and finish the job without bothering you anymore. If you remember these keystrokes, you're all set.
这在实践中是如何运作的?让我们回顾一下之前的示例,假设我们希望将 Whirligig全部更改为HealthBug (并且我们没有保存使用Replace-string所做的更改)。
How does this work in practice? Let's revisit our previous example, assuming that we want to change Whirligig to HealthBug throughout (and that we didn't save the changes we made with replace-string).
|
类型:M-< M-% Whirligig Enter HealthBug Enter Type: M-< M-% Whirligig Enter HealthBug Enter |
|
|
|
您已准备好替换第一个出现的位置;按 空格键继续。 You're ready to replace the first occurrence; press Space to go on. |
|
出版社: 太空 Press: Space |
|
|
|
当您按Space时,Emacs 会替换第一个单词;然后查询替换操作移动到第二个单词。 When you press Space, Emacs replaces the first word; the query-replace operation then moves to the second word. |
此过程将持续进行,直到到达文件末尾。正如我们所说,打字!修复文件的其余部分。
This procedure continues until you reach the end of the file. As we've said, typing ! fixes the rest of the file.
在表 3-3中,您可能已经注意到,在替换过程中,几个键(例如 Space )具有特殊含义。实际上,将这些键用于不同的功能并不容易造成混淆,尽管在纸面上听起来可能很糟糕。您可能想尝试对练习文件进行查询替换,以掌握使用不同响应的窍门。如果您很容易被逗乐,您可能会喜欢打开 Emacs FAQ,将其另存为另一个文件,然后将整个内容替换为 Emacs。
In Table 3-3, you might have noticed that several keys, such as Space, have specialized meanings while the replacement is in progress. In practice, using these keys for a different function is not confusing, though it might sound bad on paper. You might want to try a query-replace on a practice file to get the hang of using the different responses. If you are easily amused, you might enjoy opening the Emacs FAQ, saving it as another file, then replacing Emacs throughout.
现在你已经学会了 有了查询替换的基础知识,我们来讨论一个不仅适用于查询替换而且适用于 Emacs 中任何地方的快捷方式:重复复杂的命令,稍加修改。我们经常错误地退出查询替换,或者认为我们真正想要的替换只是略有不同。我们必须重新输入一遍吗?不需要。只需转到文件开头并按Cx Esc Esc即可。将显示您输入的最后一个复杂命令。如果这不是您想要的,请键入 Mp查看上一条命令(根据需要多次执行此操作;Mn 转到下一条命令)。例如,让我们转到文件的开头并重复我们刚刚执行的查询替换。
Now that you've learned the basics of query-replace, let's talk about a shortcut that applies not only in query-replace but anywhere in Emacs: repeating complex commands, with slight modifications. We often exit a query-replace by mistake or decide that the replacement we really wanted was just slightly different. Do we have to type it all again? No. Simply go the beginning of the file and press C-x Esc Esc. The last complex command you typed appears. If it's not the one you want, type M-p to see the previous command (do this as many times as necessary; M-n goes to the next command). For example, let's go to the beginning of the file and repeat the query-replace we just carried out.
|
类型:M-<后接Cx Esc Esc Type: M-< followed by C-x Esc Esc |
|
|
|
Emacs 将最后一个复杂命令放入迷你缓冲区中;事实上,它看起来比我们记忆中的更复杂。 Emacs puts the last complex command in the minibuffer; in fact it looks more complex than we remember it. |
当我们按M-<时,我们移动到文件的开头;当我们按Cx Esc Esc时,会显示最后一个复杂命令。 Emacs 用暗语自言自语,但我们仍然可以看到这是我们想要的命令。
When we press M-<, we move to the beginning of the file; when we press C-x Esc Esc, the last complex command is displayed. Emacs speaks to itself in dark words, but we can still see that this is the command that we want.
这是正确的命令,因此我们不必按 Mp来查看上一个命令。如果我们愿意,我们可以在按Enter之前更改查询替换字符串 。在这种情况下,营销部门再次将产品名称从 HealthBug(因为 bug 可能被理解为害虫)更改为 HealthBot(中性,但我们认为描述性稍差)。我们之前的查询替换将 Whirligig 更改为 HealthBug。我们需要修改此命令,以便将Bug替换为 Bot。
This is the right command, so we don't have to press M-p to see a previous command. If we wanted to, we could change the query-replace strings before pressing Enter. In this case, the Marketing Department has once again changed the product's name from HealthBug (since bug could be construed as pest) to HealthBot (neutral, but a bit less descriptive in our opinion). Our earlier query replace changed Whirligig to HealthBug. We need to modify this command so it replaces Bug with Bot.
|
在迷你缓冲区中,将Whirligig更改为 Bug,将HealthBug更改为 Bot,然后按Enter。 In the minibuffer, change Whirligig to Bug and HealthBug to Bot and press Enter. |
|
|
|
按Enter键将使用修改后的搜索和替换字符串再次执行该命令。 Pressing Enter executes the command again with the modified search and replacement strings. |
正如我们提到的,Cx Esc Esc适用于涉及迷你缓冲区中输入的任何命令,而不仅仅是查询替换。但我们最常在查询替换中使用这个功能。它对于重复键盘宏也很有用(参见 第 6 章)。
As we mentioned, C-x Esc Esc works for any command involving input in the minibuffer, not just query-replace. But we use this feature most frequently in query-replace. It is also good for repeating keyboard macros (see Chapter 6).
当您执行查询替换时,您 不可避免地会在文件中看到您想要更改的其他内容。尝试几次——您就会明白我们的意思!我们通常会尝试记住问题,直到完成为止,然后当我们忘记到底问题是什么以及问题出在哪里时,我们会感到沮丧。
When you do a query-replace, you inevitably see something else you want to change in the file. Try it a few times—you'll see what we mean! We typically try to remember the problem until we're done, then get frustrated when we forget exactly what and where the problem was.
幸运的是,Emacs 提供了一种更简单的方法。它允许您在查询替换过程中开始递归编辑。通过开始递归编辑,您可以在进行任何其他所需编辑时有效地暂停查询替换。当您退出递归编辑时,查询替换将从您上次中断的位置继续。
Fortunately, Emacs provides an easier way. It allows you to start a recursive edit while you're in the middle of a query-replace. By starting a recursive edit, you effectively put query-replace on hold while you make any other desired edits. When you exit the recursive edit, the query-replace resumes where you left off.
在以下位置开始递归编辑
查询-替换,按Cr。 (请注意,与许多其他键绑定一样,
Cr在查询替换中的含义与在标准 Emacs 中的含义不同。)当您开始递归编辑时,方括号 ( [ ]) 会出现在模式行上。让我们再回到我们的公共关系部分。你已经用query-replace找到了第一个要改成Bot的Bug,正准备按
空格键修复它,这时你想起律师说“64盎司水”的说法太具体了,可能解释为提供医疗建议。快速递归编辑可以挽救局面。
To start a recursive edit while in
query-replace, press C-r. (Note that like many other key bindings,
C-r has a different meaning in
query-replace than it does in standard Emacs.) When you start a
recursive edit, square brackets ([ ]) appear on
the mode line. Let's go back, one more time, to our
public relations piece. You've used query-replace to
find the first Bug to change to Bot, and you are about to press
Space to fix it, when you remember
that the lawyers said that the "64 ounces of
water" statement was too specific and could be
construed as giving medical advice. A quick recursive edit saves the
day.
|
类型:铬 Type: C-r |
|
|
|
请注意 周围的方括号 Notice the square brackets around |
现在进行任何您想要的编辑;您正处于编辑模式,就像标准 Emacs 一样。向下移动到第三行并删除“64 盎司”。当您想要恢复查询替换时,请按CMc。该命令告诉 Emacs 离开递归编辑并重新激活查询替换。 Emacs 返回到开始递归编辑时所在的位置。然后您可以继续进行替换,就像什么都没发生一样。
Now do any editing you want to; you are in an editing mode just like standard Emacs. Move down to the third line and delete "64 ounces of." When you want to resume the query-replace, press C-M-c. This command tells Emacs to leave the recursive edit and reactivate the query-replace. Emacs moves back to the point where you were when you started the recursive edit. You can then continue making replacements just as if nothing had happened.
|
删除“64 盎司”,然后输入 CMc Delete "64 ounces of," then type C-M-c |
|
|
|
Emacs 返回查询替换,然后按空格键修复下一个 Bug。 Emacs goes back to query-replace and you press Space to fix the next Bug. |
如果您决定退出递归编辑并一次性取消查询替换,您可以键入C-] (用于abort-recursive-edit)或 Mx 顶级 Enter而不是 CMc。
If you decide to exit the recursive edit and cancel the query-replace in one fell swoop, you can type C-] (for abort-recursive-edit) or M-x top-level Enter rather than C-M-c.
事实上,您可以随时开始递归编辑,而不仅仅是在查询替换时。命令Mx recursive-edit Enter使您进入递归编辑;CMc让您脱离递归编辑,并让您回到之前所做的事情。您甚至可以在递归编辑中进行递归编辑,尽管随着每个新级别的增加,混淆的可能性也会增加。
In fact, you can start a recursive edit at any time, not just when you're in a query-replace. The command M-x recursive-edit Enter puts you into a recursive edit; C-M-c takes you out of the recursive edit and brings you back to what you were doing before. You can even have recursive edits within recursive edits, although the possibility for confusion increases with each new level.
默认情况下,Emacs 搜索 不区分大小写。查看“选项”菜单,您会发现 选项“不区分大小写搜索”是默认选中的唯一选项。
By default, Emacs searches are not case-sensitive. Look at the Options menu and you'll see that the option Case-Insensitive Search is the only option that is checked by default.
这在实践中意味着什么?如果您搜索“random”一词 ,则会找到 random、Random和 RANDOM,以及诸如 RanDoM和rANdOM之类的奇怪内容。在进行替换时,Emacs 会注意被替换单词的形式,并用相同的大小写进行替换。如果将 random替换为tandem, 则 Random将替换为 Tandem,并且RANDOM将替换为TANDEM。如果混合使用大小写,则替换字符串会在您键入时出现。 如果替换字符串中出现这种情况,则healthbug将被替换为 HealthBug 。换句话说,默认的搜索和替换操作通常会执行您想要的操作:它们会查找搜索字符串,无论其大小写如何,并根据其上下文适当调整替换。然而,有时您需要更精细的控制。
What does this mean in practical terms? If you search for the word random, the search finds random, Random, and RANDOM, as well as oddities like RanDoM and rANdOM. When doing replacements, Emacs pays attention to the form of the word being replaced and replaces it with the same case. If you replaced random with tandem, Random would be replaced with Tandem, and RANDOM would be replaced with TANDEM. If you mix capitalization, the replacement string appears just as you type it. healthbug would be replaced with HealthBug if that was the case in the replacement string. In other words, the default search and replacement operations usually do what you want: they find a search string regardless of its case and adjust the replacement appropriately for its context. However, sometimes you need finer control.
变量case-fold-search 决定 搜索是否区分大小写。它适用于所有搜索:增量搜索、单词搜索、搜索和替换操作中的搜索等等。默认情况下,case-fold-search设置为t,这意味着“忽略大小写,除非用户输入混合或大写字母”。这种合理的默认设置通常正是您想要的。但如果您需要区分大小写的搜索,“选项”菜单上的“不区分大小写的搜索”选项提供了一种简单的方法来试验此变量。
The variable case-fold-search determines whether searches are case-sensitive. It applies to all searches: incremental searches, word searches, searches within search-and-replace operations, and so on. By default, case-fold-search is set to t, which means "ignore case unless the user types in mixed or uppercase." This sensible default is usually just what you want. But if you need case-sensitive searches, the Case-Insensitive Search option on the Options menu provides an easy way to experiment with this variable.
同样,如果您不希望 Emacs 调整替换字符串的大小写,您可以设置变量 case-replace。同样,它的默认值是 t(代表“true”),这意味着“调整替换字符串的大小写以匹配原始文本”,也就是说,如果原始单词大写,则将替换字符串大写,依此类推。将此变量设置为nil意味着“永远不要调整替换字符串的大小写;始终将其完全按照我键入的方式输入”。要更改case-replace的值,请键入 Mx set-variable Enter case-replace Enter nil Enter(此变量没有菜单选项)。
Likewise, if you don't want Emacs to adjust the case of your replacement strings, you can set the variable case-replace. Again, its value is t (for "true") by default, which means "adjust the case of a replacement string to match the original text"—that is, capitalize the replacement if the original word was capitalized and so on. Setting this variable to nil means "never adjust the case of the replacement string; always put it in exactly as I typed it." To change the value of case-replace, type M-x set-variable Enter case-replace Enter nil Enter (there's no menu option for this variable).
菜单选项和set-variable命令都只能暂时改变 Emacs 的行为。如果您开始新的编辑会话,您将恢复到默认行为。这可能就是您想要的,因为单独搜索大写和小写单词很不方便。
Both the menu option and the set-variable command change the behavior of Emacs only temporarily. If you start a new editing session, you'll be back to the default behavior. This is probably what you want, because searching separately for capitalized and lowercase words is inconvenient.
您可以通过从“选项”菜单中选择“保存选项”或将此行添加到您的.emacs文件来永久设置“不区分大小写搜索”选项的值:
You can set the value for the Case-Insensitive Search option permanently by selecting Save Options from the Options menu or by adding this line to your .emacs file:
(setq-默认大小写折叠搜索 nil) ;需要精确匹配
(setq-default case-fold-search nil) ; require exact matches
要永久设置大小写替换,请将以下行添加到您的.emacs文件中。您需要重新启动 Emacs 才能使更改生效。
To set case-replace permanently, add the following line to your .emacs file. You'll need to restart Emacs to have the change take effect.
(setq-默认大小写-替换 nil) ;替换时切勿更改大小写
(setq-default case-replace nil) ; never change case when replacing
您可以通过 Emacs 的交互式定制工具 Custom 来更改这些变量(参见第 10 章)。
You could change these variables through Emacs's interactive customization facility, Custom, instead (see Chapter 10).
有时没有一个更简单 本章中描述的搜索就足够了。正则表达式允许您使用包含各种通配符的字符串构建搜索。
Sometimes none of the simpler searches described in this chapter are adequate. Regular expressions allow you to build searches with strings that contain various wildcards.
表 3-4显示了一些 可用于创建正则表达式的字符。
Table 3-4 shows some of the characters you can use in creating a regular expression.
表 3-4。用于创建正则表达式的字符
Table 3-4. Characters for creating regular expressions
|
人物) Character(s) |
匹配 Match |
|---|---|
|
^ ^ |
匹配行的开头。 Matches the beginning of a line. |
|
$ $ |
匹配行尾。 Matches the end of a line. |
|
。 . |
匹配任何单个字符(例如文件名中的 ?)。 Matches any single character (like ? in filenames). |
|
.* .* |
匹配任何零个或多个字符的组(. 匹配任何字符,* 匹配零个或多个前一个字符)。 Matches any group of zero or more characters (. matches any character and * matches zero or more of the previous character). |
|
\< \< |
匹配单词的开头。 Matches the beginning of a word. |
|
\> \> |
匹配单词的结尾。 Matches the end of a word. |
|
[ ] [ ] |
匹配括号内指定的任何字符;例如,[az] 匹配任何字母字符。 Matches any character specified within the brackets; for example, [a-z] matches any alphabetic character. |
|
\s,\S \s, \S |
匹配任何空白字符:空格、换行符、制表符、回车符、换页符或退格符; \S 匹配除空格之外的任何字符。 Matches any whitespace character: space, a newline, a tab, a carriage return, a formfeed, or a backspace; \S matches any character except whitespace. |
|
\d,\D \d, \D |
匹配任意一位数字,0-9; \D 匹配除数字之外的任何字符。 Matches any single digit, 0-9; \D matches any character but a digit. |
|
\w,\W \w, \W |
匹配任何“单词”字符(大小写字母、数字和下划线字符); \W 匹配除这些字符之外的任何字符。 Matches any "word" character (upper- and lowercase letters, digits, and the underscore character); \W matches any character but these. |
如果您对^word$进行正则表达式搜索,您将 在一行中找到单词的实例。 ^表示w必须是该行的第一个字符, $表示d必须是最后一个字符。
If you do a regular expression search for ^word$, you would find instances of word on a line by itself. The ^ says that the w must be the first character on the line, the $ says that the d must be the last character.
如果您想查找以 beg开头并以字母 s结尾的所有单词,您可以使用beg[az]*s作为正则表达式。除了像shibegrees和 altbegaslia这样非常奇怪的单词之外,这会找到单词begins、 begets和begonias。如果您不想要这些突变体,也就是说,如果您确实想要以 beg开头并以s结尾的单词,请使用 \<beg[az]*s\>。 \ <是匹配单词开头的特殊序列;\>匹配单词的结尾。如果您想查找单词 “beg”、“big”和 “bag”;但不是begonias,当然也不是任何内部带有beg 的奇怪单词,您可以使用\<b[az]g\>作为正则表达式。
If you wanted to find all words starting with beg and ending with the letter s, you could use beg[a-z]*s as your regular expression. This would find the words begins, begets, and begonias, in addition to really odd words like shibegrees and altbegaslia. If you don't want these mutants—that is, if you really want words that begin with beg and end with s, use \<beg[a-z]*s\>. The \< is a special sequence that matches the beginning of a word; \> matches the end of a word. If you wanted to find the words beg, big, and bag; but not begonias, and certainly not any strange words with beg on the inside, you would use \<b[a-z]g\> as the regular expression.
搜索^、$、 . 、 *、[、]或任意数量的 其他特殊字符,显然不能使用该字符本身。首先放置一个反斜杠 (\) — 即,要搜索句点,请搜索 \。例如,要搜索电子邮件地址`:
To search for a ^, $, ., *, [, ], or any number of other special characters, you obviously can't use the character itself. Put a backslash (\) first—i.e., to search for a period, search for \. For example, to search for the electronic mail address`:
howie@mcds.com
howie@mcds.com
正则表达式为:
the regular expression would be:
howie@mcds\.com
howie@mcds\.com
这是对正则表达式的简单介绍;请参阅第 11 章了解更多详细信息,并参阅 Jeffrey Friedl (O'Reilly) 的《掌握正则表达式》了解该主题的全书长度的处理。
This is a barebones introduction to regular expressions; see Chapter 11 for more details and Mastering Regular Expressions by Jeffrey Friedl (O'Reilly) for a book-length treatment of this topic.
您可以使用正则表达式 增量搜索和查询替换。表 3-5列出了用于正则表达式搜索的命令。尽管他们的发起略有 不同的命令,搜索与本章前面描述的相同。
You can use regular expressions in incremental searches and in query-replace. Table 3-5 lists the commands you use for regular expression searches. Although they are initiated with slightly different commands, the searches are the same as those described earlier in this chapter.
表 3-5。正则表达式搜索命令
Table 3-5. Regular expression search commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CM 输入 编辑 → 搜索 → 正则表达式转发 C-M-s Enter Edit → Search → Regexp Forward |
研究向前 re-search-forward |
向前搜索正则表达式。 Search for a regular expression forward. |
|
CMr 输入 编辑 → 搜索 → 正则表达式向后 C-M-r Enter Edit → Search → Regexp Backwards |
向后研究 re-search-backward |
向后搜索正则表达式。 Search for a regular expression backward. |
|
CM 编辑 → 搜索 → 增量搜索 → 正向正则表达式 C-M-s Edit → Search → Incremental Search → Forward Regexp |
isearch-forward-正则表达式 isearch-forward-regexp |
逐步向前搜索正则表达式。 Search incrementally forward for a regular expression. |
|
CMR 编辑 → 搜索 → 增量搜索 → 向后正则表达式 C-M-r Edit → Search → Incremental Search → Backward Regexp |
isearch-向后-正则表达式 isearch-backward-regexp |
向后增量搜索正则表达式。 Search incrementally backward for a regular expression. |
|
CM-% 编辑 → 替换 → 替换正则表达式 C-M-% Edit → Replace → Replace Regexp |
查询替换正则表达式 query-replace-regexp |
查询-替换正则表达式。 Query-replace a regular expression. |
|
(没有任何) (none) |
替换正则表达式 replace-regexp |
无条件全局替换正则表达式(谨慎使用)。 Globally replace a regular expression unconditionally (use with caution). |
Emacs 包含两个拼写检查接口:Unix 拼写检查器spell和 Ispell,许多人(包括我们)都更喜欢后者。我们说“接口”是因为 Emacs 不包含这些拼写检查器的可执行文件。由于 Ispell 非常出色并且可以在多种平台上运行,因此我们在这里仅介绍 Ispell。如果您尝试运行 Ispell 但它不可用,则必须安装它。第 13 章提供了有关在 Windows 和 Mac OS X 上安装 Ispell 的详细信息。
Emacs includes two spell-checking interfaces: to the Unix spell
checker, spell, and to Ispell, which many people,
including us, prefer. We say
"interfaces" because Emacs does not
include the executables for either of these spell-checkers. Because
Ispell is superior and runs on a variety of platforms,
we'll cover only Ispell here. If you attempt to run
Ispell and it is not available, you'll have to
install it. Chapter 13 provides details on
installing Ispell on Windows and on Mac OS X.
Flyspell 是 Ispell 的进一步增强功能,该命令可以即时突出显示拼写错误的单词。如果您安装了 Ispell,您也将获得 Flyspell 支持。
A further enhancement to Ispell is Flyspell, a command that highlights misspelled words on the fly. If you have Ispell installed, you'll have Flyspell support as well.
Ispell 包括以下选项
检查缓冲区、区域、程序中的注释或单个单词。输入命令告诉 Ispell 要检查哪个区域后,它对所有这些选项的工作方式都是相同的。我们将在这里描述ispell-buffer。如果所有单词拼写正确,Ispell 将显示消息
Spell-checking done。如果 Ispell 发现拼写错误的单词,则会出现如下屏幕。让我们检查一下荷马
史诗《奥德赛》中匆匆打字的一段文字的拼写。
Ispell includes options to
check a buffer, a region, the comments in
a program, or a single word. After you type the command telling
Ispell what area you want to check, it works the same way for all
these options. We'll describe ispell-buffer here. If all the words are
spelled correctly, Ispell displays the message,
Spell-checking done. If Ispell finds a misspelled word, a screen
like the following appears. Let's spell-check a
hastily typed passage from Homer's
Odyssey.
|
类型:Esc x ispell-buffer Enter Type: Esc x ispell-buffer Enter |
|
|
|
Ispell 在缓冲区中找到第一个无法识别的单词。 Ispell finds the first unrecognized word in the buffer. |
Ispell 移动到第一个无法识别的单词,在本例中是正确拼写的专有名称(正确的重音符号除外)。 Ispell 在屏幕顶部打开一个小窗口,显示替代拼写,编号从 0 开始。迷你缓冲区显示
C-h or ? for more options, SPC to leave unchanged, character
to replace word。在这种情况下,我们有一个拼写正确的名字,所以按i要求 Ispell 将其插入到您的私人名字中
字典,保存在您的主目录中名为.ispell_<language>的文件中, [ 1 ],其中language是
您正在使用的语言(默认为英语)。如果此文件不存在,Ispell 会毫无怨言地创建它,然后询问您是否要保存它。要将小写单词插入词典中,请按u,Ispell 会小写该单词,然后将其放入词典中。当然,因为这是一个专有名称,我们按照它在段落中出现的样子插入它。
Ispell moves to the first unrecognized word, in this case a proper
name correctly spelled (except for the proper accent marks). At the
top of the screen, Ispell opens a small window that displays
alternative spellings, numbered starting with 0. The minibuffer says
C-h or ? for more options, SPC to leave unchanged, character
to replace word. In this case, we have a properly spelled
name, so press i to ask Ispell to
insert it into your private
dictionary, which is kept in a
file called .ispell_<language> in your
home directory,[1] where language is the
language you are using (English by default). If
this file doesn't exist, Ispell creates it without
complaint and later asks you if you want to save it. To insert the
word in the dictionary in lowercase, press u and Ispell lowercases the word and then puts
it into your dictionary. Of course, because this is a proper name, we
insert it as it appears in the passage.
|
按我: Press i: |
|
|
|
Ispell 移动到下一个无法识别的单词,即另一个专有名称。 Ispell moves to the next unrecognized word, another proper name. |
|
我们插入一些更多的专有名称,然后继续讨论第一个真正的拼写错误pwers。 We insert a few more proper names and move along to the first real misspelling, pwers. |
|
|
|
Ispell 发现pwers拼写错误。 Ispell finds pwers misspelled. |
Ispell 在屏幕顶部打开一个窗口,列出替换选项。通常它的前几个选择之一是正确的。
Ispell opens a window at the top of the screen listing choices for a replacement. Usually one of its top few choices is correct.
|
要选择功率,请按:1 To select powers, press: 1 |
|
|
|
Ispell 替换了该单词并继续处理下一个拼写错误。 Ispell replaces the word and goes on to the next misspelling. |
如果 Ispell 在屏幕顶部列出的单词之一正确,您可以键入数字,Ispell 会进行替换。要自行替换单词,请按r。输入更正的单词后,Ispell 会替换它。如果您按 R,Ispell 将启动查询替换,通过它您可以更正此缓冲区中的所有拼写错误情况。
If one of the words that Ispell lists at the top of the screen is correct, you type the number, and Ispell makes the replacement. To replace a word yourself, press r. After you type the corrected word, Ispell replaces it. If you press R instead, Ispell starts a query-replace through which you can correct all cases of the misspelling in this buffer.
而不是更换 换句话说,您可能只是希望 Ispell 跳过它。要跳过拼写错误的单词,请按 Space。要在所有缓冲区的其余会话中忽略拼写错误的单词,请按a(表示接受)。大写字母A有一个细微的差别:它告诉 Ispell 接受本次会话的单词,但仅在此缓冲区中。
Instead of replacing the word, you may simply want Ispell to skip over it. To skip this occurrence of a misspelled word, press Space. To ignore a misspelled word for the rest of the session for all buffers, press a (for accept). Uppercase A has one subtle difference: it tells Ispell to accept the word for this session but only in this buffer.
如果您发现更复杂的错误,您可以通过输入Cr开始递归编辑。修复错误并输入CMc退出递归编辑并恢复 Ispell。 (您可能还记得我们在本章前面讨论过递归编辑。)
If you can see that something more complicated is wrong, you can start a recursive edit by typing C-r. Fix the error and type C-M-c to exit the recursive edit and resume Ispell. (You may recall that we discussed recursive editing earlier in this chapter.)
我们的段落反复拼写错误,并且在正确单词旁边键入字符只会替换单个事件,因此更好的选择是键入R来查询替换整个缓冲区中的单词。
Our passage repeatedly spells would incorrectly and typing the character beside the correct word only replaces a single incidence, so a better choice would be to type R to query-replace the word throughout the buffer.
|
将wald更改为will并按Enter。 Change wuld to would and press Enter. |
|
|
|
Ispell 启动查询替换。 Ispell starts a query-replace. |
我们想要替换所有出现的拼写错误单词,因此我们将输入!,您可能还记得,这意味着“无需询问即可全部替换”。
We want to replace all occurrences of the misspelled word, so we'll type !, which, as you might recall, means "replace them all without asking."
|
类型!然后 当提示保存您的个人词典时y 。 Type ! then y when prompted about saving your personal dictionary. |
|
|
|
Emacs 转向“下一个”拼写错误crse。 Emacs moves to the "next" misspelling, crse. |
Ispell 取代了这些词, 然后继续下一个拼写错误 crse。请注意,此拼写错误发生在第二个错误wuld之前。因为我们已经将wuld查询替换为 will,所以 Ispell 必须向后移动才能找到下一个拼写错误。
Ispell replaces the words, then goes on to the next misspelling, crse. Note that this misspelling occurs before the second incorrect wuld. Because we already query-replaced wuld with would, Ispell had to move backward to find the next misspelling.
请记住,Ispell 与所有拼写检查器一样,仅更正真正的拼写错误。如果拼写错误形成了另一个单词,Ispell 将不理会它。在这段话中,由你来将 薯条改为火。
Remember that Ispell, like all spellcheckers, corrects only true misspellings. If a misspelling forms another word, Ispell will leave it alone. It's up to you to change fries to fires in this passage.
同一词的不同形式必须分别更正。例如,如果您拼错了receive、 receive以及通过颠倒i和e来接收,则必须更改每个拼写错误的单词。
Different forms of the same word must be corrected separately. For example, if you misspell receive, receives, and receiving by reversing the i and the e, you must change each misspelled word.
有时当你
当你打字时,你会说,“这看起来不对。”要检查光标所在的单词,请输入
M-$(代表ispell-word)。 Ispell 检查单词的拼写并显示单词拼写是否正确。如果单词不正确,Ispell 将显示一个窗口,其中包含前面讨论的选项。word
:
ok
Sometimes when you
are typing, you'll say,
"That doesn't look
right." To check the word the cursor is on, type
M-$ (for ispell-word). Ispell checks the spelling of
the word and displays word
:
ok if the word is spelled correctly. If the word is
incorrect, Ispell displays a window with the options discussed
earlier.
您可能会开始输入 然后想知道“这个词是怎么拼写的?”这就是ispell-complete-word发挥作用的地方。您正在输入一个单词,然后就卡住了。输入 M-Tab(代表ispell-complete-word),您将得到一个选项列表。输入“ occurred”后,您可以使用此命令来找出答案。
You might start typing a word and then wonder, "How is that spelled?" This is where ispell-complete-word comes in. You're typing a word and you get stuck. Type M-Tab (for ispell-complete-word) and you get a list of choices. After typing occur, you use this command to find out the answer.
此功能的实用性各不相同。在这种情况下,显示了所需的更换。它并不总是这样工作,但你总是可以简单地拼写错误,然后使用ispell-buffer来修复它。
This feature varies in its helpfulness. In this case the replacement needed was shown. It won't always work that way, but you can always simply spell it wrong and then use ispell-buffer to fix it.
Flyspell 突出显示拼写错误 您键入的单词。您还可以使用它来检查现有文本。执行此操作的命令不同。
Flyspell highlights misspelled words as you type. You can also use it to check existing text. The commands for doing this are different.
要在键入时检查文本,请输入Mx Flyspell-mode Enter进入 Flyspell 模式。
Fly出现在模式行上。如果您将 Emacs 设置为自动进入 Flyspell 模式,则您的文本始终会“即时”进行拼写检查。 Flyspell 模式的替代方案是 Flyspell prog 模式。在这种专为程序员设计的模式下,Emacs 仅突出显示注释或字符串中的拼写错误。要输入它,请输入Mx Flyspell-prog-mode Enter。
To check text as you type, enter Flyspell mode by typing M-x flyspell-mode Enter.
Fly appears on the mode line. If you set up Emacs
to enter Flyspell mode automatically, your text is always
spell-checked "on the fly." An
alternative to Flyspell mode is Flyspell prog mode. In this mode,
designed for programmers, Emacs highlights misspellings only in
comments or strings. To enter it, type M-x
flyspell-prog-mode Enter.
要检查现有文本,请运行Mx Flyspell-buffer Enter。这个命令就像ispell-buffer;它对整个缓冲区进行拼写检查。 Flyspell 的界面有所不同;它会在所有怀疑拼写错误的单词下划线,并为您提供一个替代选项的弹出菜单。
To check existing text, you run M-x flyspell-buffer Enter. This command is like ispell-buffer; it spell-checks the entire buffer. Flyspell's interface is different; it underlines all the words it suspects are misspelled and gives you a pop-up menu of alternatives.
查看 Flyspell 模式的最佳方法是将其打开并输入一些拼写错误的文本以查看其实际情况。无论您是进入 Flyspell 模式还是运行Flyspell-buffer,您都会以相同的方式纠正错误。我们将在拼写错误的 奥德赛文件中演示Flyspell-buffer。因为它是一个现有文件(不是我们正在输入的新文件),所以我们需要发出Flyspell-buffer 命令。
The best way to check out Flyspell mode is to turn it on and type some misspelled text to see it in action. No matter whether you enter Flyspell mode or run flyspell-buffer, you correct errors in the same way. We'll demonstrate flyspell-buffer on our misspelled odyssey file. Because it's an existing file (not a new file we're typing), we need to issue the flyspell-buffer command.
|
类型:Esc x Flyspell-buffer Enter Type: Esc x flyspell-buffer Enter |
|
|
|
Flyspell 突出显示拼写错误的单词 (Mac OS X)。 Flyspell highlights misspelled words (Mac OS X). |
Flyspell亮点 红色拼写错误的单词。反复拼写错误的单词以黄色突出显示。请注意,它不会突出显示我们之前使用 Ispell 在字典中插入的专有名称; Flyspell 检查单词是否在您的个人词典中,然后将其突出显示为错误。
Flyspell highlights misspelled words in red. Words that are repeatedly misspelled are highlighted in yellow. Note that it doesn't highlight the proper names we inserted in the dictionary earlier using Ispell; Flyspell checks to see whether words are in your personal dictionary before highlighting them as errors.
您移动到拼写错误的单词并按鼠标中键以显示可能替换的弹出菜单。 (这意味着您有一个三键鼠标,而且说实话,您需要一个才能使 Flyspell 正常工作。)您使用鼠标选择替代品。
You move to a misspelled word and press the middle mouse button to display a pop-up menu of possible replacements. (This implies that you have a three-button mouse, and, to be honest, you need one to make Flyspell work properly.) You select a replacement using the mouse.
|
将光标移至crse并按鼠标中键。 Move the cursor to crse and press the middle mouse button. |
|
|
|
Flyspell 显示替代方案的弹出窗口;您可以使用鼠标选择一个 (Mac OS X)。 Flyspell displays a pop-up window of alternatives; you choose one with the mouse (Mac OS X). |
|
用鼠标选择诅咒。 Choose curse with the mouse. |
|
|
|
Emacs 插入正确的替换 (Mac OS X)。 Emacs inserts the correct replacement (Mac OS X). |
Ispell 在词典中插入新单词。 Flyspell 更进一步,创建了单词缩写 你拼写错误的单词。本质上,单词缩写告诉 Emacs,在这种情况下,wrd只是 word的缩写,因此 Emacs 应该自动替换它。如果您打开单词缩写模式(如下一节所述),Flyspell 遇到的长期拼写错误将被自动纠正。
Ispell inserts new words in the dictionary. Flyspell takes it a step further, creating word abbreviations for words that you misspell. In essence, a word abbreviation tells Emacs, in this case, that wrd is just an abbreviation for word, and that therefore Emacs should replace it automatically. If you turn on word abbreviation mode, described in the next section, chronic misspellings that Flyspell encounters will be automatically corrected.
如何判断 Flyspell 正在使用单词缩写?当您退出使用 Flyspell 的会话时,您会看到一条提示:Save
abbrevs
in
~/.abbrev_defs (y
or
n)。如果不打开单词缩写模式,无论是在启动时还是手动,都不会发生这种自动更正。请阅读本章中有关此主题的部分以获取更多详细信息。
How can you tell Flyspell is using word abbreviations? When you exit
a session in which you've used Flyspell, you see a
prompt that says, Save
abbrevs
in
~/.abbrev_defs (y
or
n). This automatic
correction won't occur without turning on word
abbreviation mode, whether in your startup or manually. Read the
section on this topic in this chapter for more details.
如果遇到拼写正确但 Flyspell 无法识别的单词,您该怎么办?如果它是您经常使用的单词,您可以将其插入 Ispell 词典中。 Flyspell 弹出菜单上的“保存单词”选项可以处理此问题。作为临时修复,选项 Accept buffer 和 Accept session 告诉 Flyspell 自动接受当前缓冲区或当前 Emacs 会话中所有缓冲区的单词。当然,如果这是您经常使用的单词,您可能需要将其插入 Ispell 词典中,以防止 Flyspell 每次都对其进行标记。
What do you do if you encounter a word that's spelled correctly but that Flyspell doesn't recognize? You could insert it in your Ispell dictionary if it's a word you use frequently. The Save word option on the Flyspell pop-up menu handles this. For a temporary fix, the options Accept buffer and Accept session tell Flyspell to accept a word for the current buffer or for all buffers in the current Emacs session automatically. Of course, if it's a word you use frequently, you may want to insert it in the Ispell dictionary to keep Flyspell from flagging it each time.
要自动进入 Flyspell 模式,请将此行添加到您的 .emacs文件中:
To enter flyspell mode automatically, add this line to your .emacs file:
(setq-默认 Flyspell-模式 t)
(setq-default flyspell-mode t)
表 3-6总结了 Ispell 和 Flyspell 命令。
Table 3-6 summarizes the Ispell and Flyspell commands.
表 3-6。拼写检查命令
Table 3-6. Spell-checking commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
M-$ 工具 → 拼写检查 → 单词拼写检查 M-$ Tools → Spell Checking → Spell-Check Word |
拼写单词 ispell-word |
检查光标所在的单词或光标后面的单词。 Check the word the cursor is on or the word following the cursor. |
|
(无)工具 → 拼写检查 → 拼写检查区域 (none)Tools → Spell Checking → Spell-Check Region |
ispell 区域 ispell-region |
检查该区域的拼写。 Check spelling of the region. |
|
(无)工具 → 拼写检查 → 拼写检查缓冲区 (none)Tools → Spell Checking → Spell-Check Buffer |
ispell 缓冲区 ispell-buffer |
检查缓冲区的拼写。 Check spelling of the buffer. |
|
(无)工具 → 拼写检查 → 拼写检查消息 (none)Tools → Spell Checking → Spell-Check Message |
ispell-消息 ispell-message |
检查邮件正文的拼写。 Check spelling of the body of a mail message. |
|
(无)工具 → 拼写检查 → 拼写检查注释 (none)Tools → Spell Checking → Spell-Check Comments |
ispell 注释和字符串 ispell-comments-and-strings |
检查程序中注释和字符串的拼写。 Check spelling of comments and strings in a program. |
|
Cu M-$ 工具 → 拼写检查 → 继续拼写检查 C-u M-$ Tools → Spell Checking → Continue Spell-Checking |
ispell-继续 ispell-continue |
恢复 Ispell;仅当使用Cg停止 Ispell 时它才有效。 Resume Ispell; it works only if stopped Ispell with C-g. |
|
(没有任何) (none) |
ispell-kill-ispell ispell-kill-ispell |
终止 Ispell 进程,该进程在调用后继续在后台运行。 Kill the Ispell process, which continues to run in the background after it is invoked. |
|
M-Tab 工具 → 拼写检查 → 完整单词 M-Tab Tools → Spell Checking → Complete Word |
ispell 完整单词 ispell-complete-word |
在文本模式下,列出当前单词可能的补全。 In text mode, list possible completions for the current word. |
|
(无)工具 → 拼写检查 → 自动拼写检查 (Flyspell) (none)Tools → Spell Checking → Automatic Spell-Checking (Flyspell) |
飞行咒语模式 flyspell-mode |
进入 Flyspell 小模式,其中拼写错误的单词会突出显示。 Enter the Flyspell minor mode, in which incorrectly spelled words are highlighted. |
|
(没有任何) (none) |
Flyspell缓冲区 flyspell-buffer |
对当前缓冲区进行拼写检查,为所有拼写错误的单词添加下划线。使用鼠标中键进行更正。 Spell-check the current buffer, underlining all misspelled words. Use middle mouse button to correct. |
[ 1 ]您的默认字典可能完全被称为其他名称,例如 .aspell.language.pws。如果你运行命令 ispell-check-version,你会发现虽然 Ispell 正在运行,但它实际上是 Aspell 在幕后运行。
[1] Your default dictionary might be called something else entirely, like .aspell.language.pws. If you run the command ispell-check-version, you'll see that although Ispell is supposedly running, it's really Aspell behind the scenes.
单词缩写模式 和动态缩写是懒惰的打字员会喜欢的两个功能。作者很自豪地将自己归入该类别,因此,如果您选择探索这些功能,您将会有很好的同伴。动态缩写不太复杂,所以我们首先讨论它们。
Word abbreviation mode and dynamic abbreviations are two features that lazy typists will love. The authors proudly include themselves in that category, so you'll be in good company if you choose to explore these features. Dynamic abbreviations are less complex, so we'll discuss them first.
假设你是 一位科学家正在写一篇关于无脊椎动物的论文。您的论文中可能有许多长的技术单词,如果您像我们一样,您就会厌倦输入长单词。
Let's say that you are a scientist writing a paper on invertebrates. You're likely to have many long technical words in your paper, and if you're like us, you get tired of typing long words.
动态缩写可以解决这个问题。输入一次长单词后,您只需输入几个字母并输入命令M-/ (用于dabbrev-expand)。 Emacs 插入以该字符串开头的最近的单词。
Dynamic abbreviations come to the rescue. After you've typed a long word once, you can simply type a few letters and give the command M-/ (for dabbrev-expand). Emacs inserts the nearest word that starts with that string.
|
类型:M-/ Type: In M-/ |
|
|
|
Emacs 插入最后一个以in开头的单词,在本例中为interesting。 Emacs inserts the last word starting with in, in this case, interesting. |
有趣并不是我们所希望的这个词;而是“这是我们想要的无脊椎动物。不移动光标,再次键入M-/ 。
Interesting was not the word we were hoping for; it's invertebrates we wanted. Without moving the cursor, type M-/ again.
|
类型:M-/ Type: M-/ |
|
|
|
Emacs 插入了单词Invertebrates,这正是我们想要的。 Emacs inserts the word Invertebrates, which is what we wanted. |
正在扩展的单词不必位于文件中较早的位置即可被视为最近。 Emacs 会查看光标位置的前后,以查找它可以展开的单词。如果有符合条件的单词在光标位置上方和下方等距,Emacs 将选择上方的单词作为扩展。
The word being expanded need not be earlier in the file to be considered nearest. Emacs looks behind and ahead of the cursor position to find words it can expand. If there are eligible words that are equidistant above and below the cursor position both, Emacs selects the word that is above as the expansion.
之前我们讨论过用 Ispell 完成一个单词。动态缩写有点不同。当您完成一个单词时,该单词可能还不在缓冲区中。当您使用动态缩写时,您只是不想输入之前输入的单词,而是要求 Emacs 为您做这件事。
Earlier we talked about completing a word with Ispell. Dynamic abbreviations are a bit different. When you complete a word, the word probably isn't in the buffer (yet). When you use a dynamic abbreviation, you simply don't want to type a word you typed earlier and you're asking Emacs to do it for you.
使用动态缩写不需要像标准单词缩写那样输入特殊的次要模式。它们只是疲惫打字员的一个辅助工具。不过,单词缩写模式还有一些其他优点,例如能够为短语或习惯性拼写错误创建缩写,我们将在接下来看到。
Using dynamic abbreviations doesn't require entering a special minor mode, as standard word abbreviations do. They are simply an aid for the tired typist. Word abbreviation mode has some other advantages, though, such as the ability to create an abbreviation for a phrase or a habitual typo, as we will see next.
单词缩写模式让您 定义特殊单词和短语的缩写。你可以你 从很多方面来看它。传统上,使用缩写模式,这样您就不必完整输入长单词或短语。例如,假设您正在编写一份反复引用美国国家标准技术研究院的合同,并且不允许使用缩写词。您可以定义缩写 nist ,而不是输入全名。设置此定义后,每当您键入缩写 nist并后跟空格、制表符或标点符号时, Emacs 都会插入全名。 Emacs 会等待您输入缩写,然后自动为您扩展它。
Word abbreviation mode lets you define abbreviations for special words and phrases. You can u se it in many ways. Traditionally, abbreviation mode is used so that you don't have to type long words or phrases in their entirety. For example, let's say you are writing a contract that repeatedly references the National Institute of Standards and Technology, and you are not allowed to use an acronym. Rather than typing the full name, you can define the abbreviation nist. Once you have set up this definition, Emacs inserts the full name whenever you type the abbreviation nist, followed by a space, tab, or punctuation mark. Emacs watches for you to type an abbreviation, then expands it automatically for you.
在向您展示如何进入单词缩写模式并定义缩写列表之前,我们将从一个示例开始。我们最喜欢的单词缩写模式的非传统用途是在您键入时纠正拼写错误。[ 2 ]几乎每个人都会因为神经通路磨损而习惯性地打错十几个单词。您可以简单地告诉 Emacs,这些拼写错误是正确版本的“缩写”,Emacs 会在您每次键入它们时修复这些拼写错误;在 Emacs 修复之前,您甚至可能没有注意到您输入了错误的单词。因此,假设您已进入单词缩写模式,并且已将 receive定义为 receive的缩写;现在,当你打字时,你犯了一个无心的错误。
Before showing you how to get into word abbreviation mode and define your abbreviation list, we'll start with an example. Our favorite nontraditional use for word abbreviation mode is to correct misspellings as you type.[2] Almost everyone has a dozen or so words that they habitually type incorrectly because of worn neural pathways. You can simply tell Emacs that these misspellings are "abbreviations" for the correct versions, and Emacs fixes the misspellings every time you type them; you may not even notice that you typed the word wrong before Emacs fixes it. So assume that you've entered word abbreviation mode, and that you've defined receive as an abbreviation for recieve; now, as you're typing, you make an innocent mistake.
|
类型:您将收到 Type: You will recieve |
|
|
|
您输入了有问题的单词,但尚未按下 Space,这将提示 Emacs 进行更正(Windows)。 You type the offending word but haven't yet pressed Space, which will cue Emacs to correct it (Windows). |
|
类型: 稍后列出您要求的材料 Type: Space the materials you requested shortly |
|
|
|
按Space键后,Emacs 会自动更正单词 ;您无需停止打字,甚至无需意识到已犯错误并已更正(Windows)。 Emacs corrects the word automatically after you press Space; you need not stop typing or even be aware that a mistake has been made and corrected (Windows). |
除了能够为经常键入的短语发明缩写带来的便利之外,您还可以看到,为常见拼写错误设置简短的缩写列表可以减少校对文件所需的时间并减少常见打字错误的数量。
Besides the convenience of being able to invent abbreviations for phrases that you frequently type, you can see that setting up a short list of abbreviations for common misspellings could reduce the time it takes to proofread files and reduce the number of common typing errors.
定义缩写时,切勿使用本身就是单词的缩写,否则 Emacs 可能会在您不希望时扩展该单词,因为扩展是在不询问的情况下进行的。例如,如果您经常写有关世界复制技术协会的文章,请不要定义“疣”的缩写,否则您将无法写有关处理蟾蜍的困难。 (如果您很少使用wart这个词,以至于您认为缩写词的方便性值得使用, 那么当您确实想输入wart时,可以使用C-_来撤消缩写词。)
When you define abbreviations, never use abbreviations that are words in their own right or Emacs may expand the word when you don't want it to, because expansion takes place without asking. For example, if you frequently write about the World Association for Replicant Technology, don't define an abbreviation of wart, or you won't be able to write about the difficulties of handling toads. (If you use the word wart so infrequently that you think the convenience of the acronym warrants it, you can use C-_ to undo the abbreviation when you really want to type wart.)
Emacs 完全了解您定义的缩写。如果将receive定义为 receive 的缩写,则还必须将 receive、receive和 receive定义为缩写,以涵盖您可能拼写错误的单词的所有形式。
Emacs knows the abbreviations exactly as you define them. If you define recieve as an abbreviation for receive, you must also define recieves, recieving, and recieved as abbreviations to cover all the forms of the word you might misspell.
在继续定义一些缩写之前,您应该了解一个更基本的事实。 Emacs 根据缩写词的工作模式对其进行分类。全局缩写词适用于所有模式;本地缩写仅在定义它们的模式下起作用。例如, 如果您希望缩写仅在文本模式下工作而不是在 C 模式下工作,请在文本模式下将它们定义为本地缩写。如果您希望缩写在任何模式下工作, 将它们定义为全局的。请记住:缩写是模式的本地缩写,而不是文件或缓冲区的本地缩写。
Before you go ahead and define some abbreviations, here's one more basic fact you should know. Emacs classifies abbreviations according to which modes they work in. Global abbreviations work in all modes; local abbreviations work only in the mode in which they were defined. For example, if you want abbreviations to work only in text mode and not in C mode, define them as local while you are in text mode. If you want abbreviations to work in any mode, define them as global. Remember: abbreviations are local to modes, not to files or buffers.
Emacs 还提供了定义缩写的逆方法。此方法称为逆方法,因为您先键入缩写,然后键入定义。有些命令(我们不会讨论)让您输入定义,然后输入缩写,但它们需要一些棘手的按键序列来让 Emacs 知道光标前面有多少个单词是缩写的一部分。逆向方法更简单,并且无论缩写的定义是一个单词还是十个单词都有效。
Emacs also provides an inverse method for defining abbreviations. This method is called inverse because you type the abbreviation and then the definition. Some commands (which we won't discuss) let you type the definition and then the abbreviation, but they require some tricky key sequences to let Emacs know how many words preceding the cursor are part of the abbreviation. The inverse method is easier and it works whether the definition for the abbreviation is one word or ten words.
通常,如果您不厌其烦地定义一个单词缩写,您将在多个 Emacs 会话中使用它。但是,如果您想尝试缩写模式以查看是否要将其合并到启动中,请使用以下过程。
Usually, if you go to the trouble of defining a word abbreviation, you will use it in more than one Emacs session. But if you'd like to try out abbreviation mode to see if you want to incorporate it into your startup, use the following procedure.
To define word abbreviations for this buffer and session:
通过键入Mx abbrev-mode Enter进入单词缩写模式。Abbrev出现在模式行上。对于全局缩写,请键入您要使用的缩写,然后键入Cx aig或
Cx a -(对于add-inverse-global)。 (对于本地缩写,请键入Cx ail来代替
add-inverse-local。)然后 Emacs 会要求您进行扩展。
Enter word abbreviation mode by typing M-x
abbrev-mode Enter. Abbrev appears on
the mode line. For a global abbreviation, type the abbreviation you
want to use and type C-x a i g or
C-x a - (for add-inverse-global). (For a local
abbreviation, type C-x a i l for
add-inverse-local instead.) Emacs
then asks you for the expansion.
输入缩写的定义并按Enter。然后,Emacs 会展开缩写,并且每次您键入后跟空格或标点符号时都会这样做。
Type the definition for the abbreviation and press Enter. Emacs then expands the abbreviation and will do so each time you type it followed by a space or punctuation mark.
当您退出 Emacs 时。它询问您是否要将缩写保存在 .abbrev_defs中。如果您想保存它们,请输入y 。
When you exit Emacs. it asks if you want to save the abbreviations in .abbrev_defs. Type y if you want to save them.
您定义的缩写仅在您进入缩写模式的缓冲区中起作用。
The abbreviations you've defined will work only in buffers where you enter abbrev mode.
如果您发现喜欢使用单词缩写模式,您可能希望将其作为启动的一部分,如下节所述。
If you find that you like using word abbreviation mode, you may want to make it part of your startup, as described in the following section.
一旦您迷上了缩写模式,最简单的方法就是将其合并到您的 .emacs文件中。这该过程会创建一个单词缩写的永久文件,每次启动 Emacs 时都会加载该文件。您还可以从此文件中删除缩写;我们将在下一节中讨论如何做到这一点。
Once you become hooked on using abbreviation mode, it's easiest to incorporate it into your .emacs file. This procedure creates a permanent file of your word abbreviations that is loaded every time you start Emacs. You can also delete abbreviations from this file; we'll discuss how to do so in the next section.
要定义单词缩写并使它们成为您的启动的一部分:
To define word abbreviations and make them part of your startup:
将这些行添加到您的.emacs文件中:
(setq-默认缩写模式 t) (读取缩写文件“~/.abbrev_defs”) (setq 保存缩写 t)
Add these lines to your .emacs file:
(setq-default abbrev-mode t) (read-abbrev-file "~/.abbrev_defs") (setq save-abbrevs t)
保存.emacs文件并重新进入 Emacs。
Abbrev出现在模式行上。您可能会收到一条错误消息,指出 Emacs 无法加载您的 abbrev 文件(如果您尚未创建该文件,则可以理解)。忽略此错误消息;它不会再发生了。
Save the .emacs file and reenter Emacs.
Abbrev appears on the mode line. You may get an
error message saying Emacs can't load your abbrev
file (understandable if you haven't created the file
yet). Ignore this error message; it won't happen
again.
输入缩写并在缩写后面输入Cx aig 或Cx a - 。这些命令创建一个全局缩写;如果您想创建本地缩写,请输入Cx ail。 Emacs 要求您进行扩展。
Type an abbreviation and type C-x a i g or C-x a - following the abbreviation. These commands create a global abbreviation; if you want to create a local abbreviation instead, type C-x a i l. Emacs asks you for the expansion.
输入缩写的定义并按Enter。 Emacs 会扩展缩写,并且每次您键入后跟空格或标点符号时都会扩展缩写。您可以通过重复步骤 3 和 4 来定义任意数量的缩写。
Type the definition for the abbreviation and press Enter. Emacs expands the abbreviation and will do so each time you type it followed by a space or punctuation mark. You can define as many abbreviations as you want to by repeating Steps 3 and 4.
输入Cx Cc退出 Emacs。 Emacs 询问您是否要将缩写保存在 .abbrev_defs中。
Type C-x C-c to exit Emacs. Emacs asks if you want to save the abbreviations in .abbrev_defs.
输入y保存缩写。
Type y to save your abbreviations.
定义一些缩写并保存后,Emacs 会自动加载缩写文件。当您在后续会话中定义单词缩写时,Emacs 会再次询问您是否要保存缩写文件。回复y 以保存您定义的新缩写并让它们自动生效。
After you define some abbreviations and save them, Emacs loads the abbreviations file automatically. When you define word abbreviations in subsequent sessions, Emacs asks again whether you want to save the abbreviations file. Respond with a y to save the new abbreviations you've defined and have them take effect automatically.
如果你使用单词 经常使用缩写,您可能会定义一个缩写,然后又改变主意。您可以通过键入Mx edit-abbrevs Enter来编辑单词缩写列表。您可以通过键入Mx list-abbrevs Enter来查看(但不能编辑)该列表。
If you use word abbreviations frequently, you may define an abbreviation and later change your mind. You can edit the word abbreviation list by typing M-x edit-abbrevs Enter. You can see (but not edit) the list by typing M-x list-abbrevs Enter.
显示列表后,使用Ck (或任何其他编辑命令)删除不想使用的缩写。因为 Emacs 本身会格式化此列表,所以不要尝试编辑行或添加新行;删除是唯一安全的操作。以下是编辑单词缩写时缩写的外观。根据缩写对于特定模式是全局缩写还是局部缩写,该文件分为不同的部分:
After the list is displayed, use C-k (or any other editing commands) to delete the abbreviations you don't want to use. Because Emacs itself formats this list, don't try to edit lines or add new lines; deleting is about the only operation that's safe. Here's how the abbreviations look when you edit word abbreviations. The file is divided into different sections based on whether the abbreviations are global or local to a particular mode:
(文本模式缩写表) (lisp 模式缩写表) (基本模式缩写表) (全局缩写表) “i没有” 1 “没有” “短语” 1 “短语” “那个” 1 “那个” “fo”1“的” “eamcs”2“Emacs” “工作”1“工作” “阿斯洛”1“也” “存储”1“存储” “信息”1“信息” “退出”6“退出” “那个” 1 “那个” “喋喋不休”1“章节” “adn”1“和” “iwth”1“与” “章节”1“章节” “位置”1“位置” “收到”1“收到” 《疣》1《世界复制技术协会》
(text-mode-abbrev-table) (lisp-mode-abbrev-table) (fundamental-mode-abbrev-table) (global-abbrev-table) "iwthout" 1 "without" "prhase" 1 "phrase" "teh" 1 "the" "fo" 1 "of" "eamcs" 2 "Emacs" "wrok" 1 "work" "aslo" 1 "also" "sotred" 1 "stored" "inforamtion" 1 "information" "esc" 6 "Esc" "taht" 1 "that" "chatper" 1 "chapter" "adn" 1 "and" "iwth" 1 "with" "chpater" 1 "chapter" "loaction" 1 "location" "recieve" 1 "receive" "wart" 1 "World Association for Replicant Technology"
该文件按模式分为多个部分。在这种情况下,我们定义了全局缩写; Flyspell(本章前面描述)创建的任何缩写都是本地缩写,并将在定义它们的模式下列出。
The file is divided into sections by mode. We defined global abbreviations in this case; any abbreviations Flyspell (described earlier in this chapter) creates are local abbreviations and would be listed under the mode in which they were defined.
在此缓冲区中,第一列列出了缩写(在本例中,大部分是拼写错误)。第二栏用于内部记录保存;你不需要担心它。第三列提供了缩写词的定义,Emacs 每当看到缩写词时都会替换的单词或短语。
In this buffer, the first column lists the abbreviations (in this case, mostly misspellings). The second column is for internal record keeping; you don't need to concern yourself with it. The third column provides the definitions of the abbreviations, the word or phrase that Emacs substitutes whenever it sees the abbreviation.
要删除任何缩写,请删除该缩写所在的行,然后通过键入Mx write-abbrev-file保存文件。您可以通过键入Cx b (用于处理多个缓冲区的命令,在第 4 章中讨论)返回到之前编辑的缓冲区。
To delete any abbreviation, delete the line for that abbreviation and save the file by typing M-x write-abbrev-file. You can move back to the buffer you were editing before by typing C-x b (a command for working with multiple buffers, discussed in Chapter 4).
你可以摆脱这个词 以两种方式之一完全缩写。首先,您可以输入Mx Kill-all-abbrevs Enter。此命令禁用当前会话的单词缩写。
You can get rid of word abbreviations completely in one of two ways. First, you can type M-x kill-all-abbrevs Enter. This command disables word abbreviations for the current session.
其次,您可以删除缩写所在的文件。如果您将单词缩写作为启动的一部分,请从 .emacs文件中删除read-abbrev-file行。
Second, you can delete the file the abbreviations are in. If you made word abbreviations part of your startup, delete the read-abbrev-file line from your .emacs file.
通常,Emacs 大写 缩写完全按照您想要的方式进行。然而,如果您遇到缩写和大写的特殊情况,您可能想知道幕后发生了什么。规则如下:
Usually, Emacs capitalizes abbreviations exactly the way you want. If you run into special situations with abbreviations and capitalization, however, you may wantl to know what's going on behind the scenes. Here are the rules:
如果缩写的定义包含任何大写字母,Emacs 始终会插入定义而不更改任何内容。例如,如果您将 ora定义为O'Reilly Media的缩写 ,则 O'Reilly将始终按所示大小写。
If the abbreviation's definition contains any uppercase letters, Emacs always inserts the definition without changing anything. For example, if you define ora as an abbreviation for O'Reilly Media, O'Reilly will always be capitalized exactly as shown.
如果缩写的定义全部小写,Emacs 将根据以下规则大写:
如果您以小写形式键入缩写的所有字母,Emacs 将以小写形式插入定义。
如果您以大写形式键入缩写的任何字母,Emacs 会将第一个单词的第一个字母大写。
如果您以大写形式输入缩写的所有字母,Emacs 会将每个单词的第一个字母大写,除非变量 abbrev-all-caps设置为t;在这种情况下,它将所有字母大写。
If the abbreviation's definition is all lowercase, Emacs capitalizes according to the following rules:
If you type all of the letters of the abbreviation in lowercase, Emacs inserts the definition in lowercase.
If you type any of the letters of the abbreviation in uppercase, Emacs capitalizes the first letter of the first word.
If you type all of the letters of the abbreviation in uppercase, Emacs capitalizes the first letter of every word, unless the variable abbrev-all-caps is set to t; in this case, it capitalizes all letters.
表 3-7显示了一些示例。
Table 3-7 shows some examples.
表 3-7。单词缩写大写
Table 3-7. Word abbreviation capitalization
|
缩写 Abbreviation |
定义 Definition |
您输入: You type: |
扩展到: Expands to: |
因为: Because: |
|---|---|---|---|---|
|
LC lc |
羊排 lamb chop |
LC lc |
羊排 lamb chop |
lc是小写的,所以羔羊排也是小写的。 lc is lowercase, so lamb chop is lowercase. |
|
LC lc |
羊排 lamb chop |
LC Lc |
羊排 Lamb chop |
Lc中有一个大写字母,因此 Lamb是大写的。 There's one capital in Lc, so Lamb is capitalized. |
|
LC lc |
羊排 lamb chop |
LC lC |
羊排 Lamb chop |
lC中有一个大写字母,因此 Lamb是大写字母。 There's one capital in lC, so Lamb is capitalized. |
|
LC lc |
羊排 lamb chop |
液相色谱 LC |
羊排 Lamb Chop |
LC全部大写,所以两个单词都要大写。 LC is all capitals, so both words are capitalized. |
|
LC lc |
羊排 Lamb Chop |
LC lc |
羊排 Lamb Chop |
定义中的大写字母始终不变。 Capitals in the definition are always unchanged. |
|
LC lc |
羊排 Lamb Chop |
液相色谱 LC |
羊排 Lamb Chop |
定义中的大写字母始终不变。 Capitals in the definition are always unchanged. |
您不需要记住这些规则,但如果您不明白 Emacs 如何利用大写,那么仔细查看它们可能会对您有所帮助。根据我们的经验,以小写形式定义缩写可以避免大多数大写问题。
You don't need to remember the rules, but looking them over may help you out if you can't understand how Emacs is capitalizing. In our experience, defining abbreviations in lowercase circumvents most capitalization problems.
表 3-8总结了单词缩写命令。
Table 3-8 summarizes word abbreviation commands.
表 3-8。单词缩写命令
Table 3-8. Word abbreviation commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
M-/ M-/ |
达布列夫-展开 dabbrev-expand |
根据以该字符串开头的最近的单词完成该单词(如果这不是您想要的单词,请再次按M-/ )。 Complete this word based on the nearest word that starts with this string (press M-/ again if that's not the word you want). |
|
(没有任何) (none) |
缩写模式 abbrev-mode |
进入(或退出)单词缩写模式。 Enter (or exit) word abbreviation mode. |
|
Cx a - 或 C-x aig C-x a - or C-x a i g |
反向添加全局缩写 inverse-add-global-abbrev |
输入全局缩写后,输入定义。 After typing the global abbreviation, type the definition. |
|
CXAIL C-x a i l |
逆加模式缩写 inverse-add-mode-abbrev |
输入本地缩写后,输入定义。 After typing the local abbreviation, type the definition. |
|
(没有任何) (none) |
未展开缩写 unexpand-abbrev |
撤消最后一个单词缩写。 Undo the last word abbreviation. |
|
(没有任何) (none) |
写入缩写文件 write-abbrev-file |
编写单词缩写文件。 Write the word abbreviation file. |
|
(没有任何) (none) |
编辑缩写 edit-abbrevs |
编辑单词缩写。 Edit the word abbreviations. |
|
(没有任何) (none) |
列表缩写 list-abbrevs |
查看单词缩写。 View the word abbreviations. |
|
(没有任何) (none) |
杀死所有缩写 kill-all-abbrevs |
杀死本次会话的缩写。 Kill abbreviations for this session. |
您搜索可以在屏幕上看到的字符串,但 Emacs 找不到它。最可能的解释 是 Emacs 正在考虑换行符和标点符号,而您没有将它们包含在搜索字符串中。使用单词搜索(忽略任何换行符或标点符号)来查找字符串。
You search for a string you can see on the screen, and Emacs can't find it. The most probable explanation is that Emacs is taking into account line breaks and punctuation, and you're not including these in the search string. Use word search, which ignores any line breaks or punctuation, to find the string.
您会收到一条消息,
内容是Searching for program: No such file or directory
ispell:。您没有安装 Ispell。 Ispell 是 Emacs 外部的;有关在 Mac OS X 和 Windows 上安装 Ispell 的详细信息,请参阅第 13 章。
You get a message that says,
Searching for program: No such file or directory
ispell. You
don't have Ispell installed. Ispell is external to
Emacs; see Chapter 13 for details on installing
Ispell on Mac OS X and Windows.
您在 Flyspell 中看不到弹出菜单。您可以通过将鼠标指向给定单词并按鼠标中键来激活此弹出菜单。本质上,您需要一个三键鼠标来运行 Flyspell。
You can't see the pop-up menu in Flyspell. You activate this pop-up menu by pointing the mouse at a given word and pressing the middle mouse button. Essentially, you need a three-button mouse to run Flyspell.
Emacs 最普遍有用的功能之一是能够同时编辑多个缓冲区并使用窗口和框架显示多个缓冲区。执行此操作的命令很简单;您只需学习几个命令,即可体验到生产力的巨大提升。您使用多个缓冲区、帧和窗口的次数越多,您就会想到它们的用途就越多。
One of the most universally useful features of Emacs is the ability to edit multiple buffers at once and to display more than one buffer using windows and frames. The commands for doing this are simple; you learn only a few commands and yet experience a tremendous boost in productivity. The more you use multiple buffers, frames, and windows, the more uses you'll think of for them.
在本章中,我们讨论如何使用缓冲区、窗口和帧。首先,我们介绍最常用的命令,然后,在缓冲区和窗口的情况下,继续讨论一些更深奥的命令。在本章的最后,我们将讨论书签,这是一种在文件中标记位置的方法。
In this chapter, we discuss how to use buffers, windows, and frames. First we cover the most commonly used commands, then, in the case of buffers and windows, move on to some more esoteric commands. At the end of the chapter, we discuss bookmarks, a method for marking your place in a file.
从概念上讲,Emacs 在两个重要方面与大多数应用程序不同。首先,它的窗口术语不同。其次,与大多数应用程序不同,Emacs 缓冲区不依赖于窗口或框架。
Conceptually, Emacs is different from most applications in two important ways. First, its window terminology is different. Second, Emacs buffers are not tied to windows or frames, unlike most applications.
让我们了解一下我们的条款
先直。 GUI 窗口不是 Emacs 窗口。 Emacs 调用 GUI Windows框架。在某种程度上,这个术语是必要的,因为 Emacs 早于 GUI,并且仍然经常在没有 GUI 窗口的终端上使用。 Emacs 窗口是分屏的。我们已经见过他们了;例如,当您请求键盘帮助时,您会看到它显示在*Help*屏幕底部的缓冲区中。图4-1和图 4-2
显示了 Emacs 框架和 Emacs 窗口。在图 4-1中,我们看到我们的dickens和odyssey
缓冲区位于两个单独的帧中。图 4-2显示了一个显示两个 Emacs 窗口的单个框架,一个在另一个之上,显示这两个文件。
Let's get our terms
straight first. GUI windows are not
Emacs windows. Emacs calls GUI windows frames.
In part, this terminology is necessary because Emacs predates GUIs
and is still often used on terminals without GUI windows. Emacs
windows are split screens. We've seen them already;
for example, when you ask for keyboard help, you see it displayed in
a *Help* buffer at the bottom of your screen.
Figures Figure 4-1 and Figure 4-2
show Emacs frames and Emacs windows. In Figure 4-1,
we see our dickens and odyssey
buffers in two separate frames. Figure 4-2 shows a
single frame displaying two Emacs windows, one on top of the other,
showing these two files.
从现在开始,当我们说框架时,我们指的是一个单独的 GUI 窗口。当我们说窗口时,我们指的是当前 Emacs 显示的一部分。从实际角度来看,我们强调这不是一个非此即彼的命题。即使您更喜欢多个框架,有时您仍然会使用 Emacs 风格的窗口。 Emacs 本身会负责这一点。
From now on, when we say frame, we mean a separate GUI window. When we say window, we mean a portion of the current Emacs display. And from a practical standpoint, we emphasize that this is not an either-or proposition. Even if you prefer multiple frames, you will still use Emacs-style windows sometimes. Emacs itself will see to that.
现在缓冲区怎么样?本质上,
窗口和框架都是显示缓冲区的方法,如
第 1 章中所定义,缓冲区可能包含文件的副本,也可能不包含文件的副本。缓冲区可能包含文件。它们可能是 Emacs 生成的缓冲区,例如
*Messages*、*scratch*或
*Help*。或者它们可能是您创建但尚未写入文件的缓冲区。
Now what about buffers? Essentially,
both
windows and frames are ways to display a buffer, which, as defined in
Chapter 1, may contain a copy of a file or not.
Buffers may contain files. They may be Emacs-generated buffers, like
*Messages*, *scratch*, or
*Help*. Or they may be buffers that you create but
haven't written to a file.
大多数 GUI 应用程序将某些文件绑定到某些 GUI 窗口,或者在 Emacspeak 中,绑定到框架。 Emacs 将缓冲区与其显示(无论是分割显示还是单独的框架)分离的功能更加强大和灵活。老实说,大多数时候我们更喜欢使用单个 Emacs 框架使用Cx b在缓冲区之间切换。它比在帧之间移动鼠标或处理分屏要容易得多,尽管每种方法在某些情况下都有其优点。
Most GUI applications tie certain files to certain GUI windows or, in Emacspeak, frames. Emacs's detachment of buffers from their display (whether a split display or a separate frame) is more powerful and flexible. To be honest, most of the time we prefer using a single Emacs frame and switching between buffers using C-x b. It's much easier than mousing between frames or dealing with a split screen, though each has its advantages in some situations.
你怎么知道有多少 Emacs 中的缓冲区是活动的,它们是什么?有三种方式:缓冲区列表(当您键入Cx Cb时出现在窗口中)、缓冲区菜单(列出活动缓冲区) 以及用于导航它们的命令),以及缓冲区弹出菜单(通过按住Ctrl并单击鼠标左键访问,其中按模式列出缓冲区)。
How do you know how many buffers are active in Emacs and what they are? There are three ways: the buffer list (which appears in a window when you type C-x C-b), the Buffers menu (which lists active buffers and commands for navigating them), and the Buffer pop-up menu (accessed by holding down Ctrl and clicking the left mouse button, which lists buffers by mode).
Emacs 创建自己的专用缓冲区。这些的名称
内部缓冲区通常具有以下格式
。、
、 和
只是 Emacs 创建的几个缓冲区。*
buffer
name
**Help**scratch**Buffer List*
Emacs creates its own specialized buffers. The names for these
internal buffers generally have the format
*
buffer
name
*. *Help*,
*scratch*, and *Buffer List*
are just a few of the buffers that Emacs creates.
当您启动 Emacs 时,它会生成两个缓冲区:
When you start Emacs, it generates two buffers:
*Messages*
|
*scratch*
|
*Messages*是一个缓冲区,其中
Emacs 从启动时和迷你缓冲区中积累消息。
*scratch*顾名思义:一个可以打字的临时便签本。除非您使用Cx Cw显式将其写入文件,否则它不会被保存。
*Messages* is a buffer where
Emacs
accumulates messages from its startup and from the minibuffer.
*scratch* is just what it sounds like: a temporary
scratchpad where you can type. It won't be saved
unless you explicitly write it to a file using C-x C-w.
当然,通常您会使用 Emacs 编辑文件。然后这些文件被复制到同名的缓冲区中。如果你寻求帮助,你也会有一个*Help*缓冲。
Of course, typically you edit files with Emacs. These files are then
copied into buffers of the same name. If you ask for help,
you'll also have a *Help* buffer.
您的缓冲区数量 能拥有真的是没有限制的。大多数时候,只显示一两个缓冲区,但即使您看不到它们,您在 Emacs 会话中创建的所有缓冲区仍然处于活动状态。您可以将它们视为一堆页面,其中一个显示为首页。您可以随时转到另一个页面(另一个缓冲区),也可以创建一个新页面。
The number of buffers you can have really has no limit. Most of the time, only one or two buffers are displayed, but even if you can't see them, all the buffers you create in an Emacs session are still active. You can think of them as a stack of pages, with the one being displayed as the top page. At any time, you can turn to another page (another buffer), or you can create a new page.
每个缓冲区都有一个关联的 主要模式决定了 Emacs 在该缓冲区中的行为方式。例如,为编写文本而设计的文本模式与为编写 Lisp 程序而设计的 Lisp 模式的行为不同。
Each buffer has an associated major mode that determines much about how Emacs behaves in that buffer. For example, text mode, designed for writing text, behaves differently from Lisp mode, which is designed for writing Lisp programs.
您可以在单独的窗口或框架或两者中显示多个缓冲区。需要记住的重要一点是,您创建的所有缓冲区都是活动的,即使它们当前没有显示。
You can display multiple buffers in separate windows or frames or both. The important thing to remember is that all the buffers you create are active even if they are not currently displayed.
如果你想创建一个 包含文件的缓冲区,只需键入 Cx Cf即可查找该文件。 Emacs 会自动创建第二个缓冲区并将您移至那里。如果缓冲区中已有该文件的副本,Cx Cf只会将您移至现有缓冲区。这一举措是明智的,而且可能确实是您想要的;如果 Cx Cf每次都从磁盘读取文件,则最终可能会得到同一文件的多个版本,每个版本都略有不同。如果您为Cx Cf提供的文件名不存在,Emacs 会假定您要使用该名称创建一个新文件,并将您移至空白缓冲区。
If you want to create a buffer that contains a file, simply type C-x C-f to find the file. Emacs automatically creates a second buffer and moves you there. If you already have a copy of the file in a buffer, C-x C-f just moves you to the existing buffer. This move is sensible and probably really what you want anyhow; if C-x C-f read the file from disk every time, you could end up with many versions of the same file that were each slightly different. If the filename you give C-x C-f doesn't exist, Emacs assumes you want to create a new file by that name and moves you to a blank buffer.
Cx Cf 后面总是跟着一个 文件名。用于在缓冲区之间移动的命令Cx b后面跟着缓冲区名称。您是否意识到模式行不显示文件名而只显示缓冲区名称?某些版本的 Emacs 显示两者,但 GNU Emacs 仅显示缓冲区名称。缓冲区名称和文件名(如果有)是相同的,除非您更改它们(请参阅本章后面的“重命名缓冲区”部分)。
C-x C-f is always followed by a filename. The command for moving between buffers, C-x b, is followed by a buffer name. Did you realize that the mode line doesn't display filenames but only buffer names? Some versions of Emacs show both, but GNU Emacs shows only the buffer name. The buffer name and the filename, if any, are the same unless you change them (see the section "Renaming Buffers," later in this chapter).
要在缓冲区之间移动,请键入Cx b。 Emacs 向您显示默认的缓冲区名称。如果这是您想要的缓冲区,请按Enter ,或者键入正确缓冲区名称的前几个字符,然后按Tab。 Emacs 填写名称的其余部分。现在按Enter键移动到缓冲区。
To move between the buffers, type C-x b. Emacs shows you a default buffer name. Press Enter if that's the buffer you want, or type the first few characters of the correct buffer name and press Tab. Emacs fills in the rest of the name. Now press Enter to move to the buffer.
您可以使用Cx b执行以下操作:
You can do the following with C-x b:
|
如果您键入 Cx b 后跟: If you type C-x b followed by: |
埃马克斯: Emacs: |
|---|---|
|
新的缓冲区名称 A new buffer name |
创建一个不与文件连接的新缓冲区并移动到那里。 Creates a new buffer that isn't connected with a file and moves there. |
|
现有缓冲区的名称 The name of an existing buffer |
将您移动到缓冲区(缓冲区是否与文件连接并不重要)。 Moves you to the buffer (it doesn't matter whether the buffer is connected with a file or not). |
如果要创建第二个(或第三个或第四个等)空缓冲区,请输入Cx b。 Emacs 要求输入缓冲区名称。您可以使用任何名称,例如Practice,然后按Enter。 Emacs 创建缓冲区并将您移至那里。例如,假设您一直在研究经过验证的dickens缓冲区。但你想要一些新的东西,所以你开始一个新的缓冲区来玩詹姆斯·乔伊斯的一些散文。
If you want to create a second (or third or fourth, etc.) empty
buffer, type C-x b. Emacs asks for a
buffer name. You can use any name, for example, practice, and press Enter. Emacs creates the buffer and moves you
there. For example, assume you've been working on
your tried-and-true dickens buffer. But
you'd like something new, so you start a new buffer
to play with some prose from James Joyce.
此过程与使用Cx Cf没有什么不同
;唯一的区别是新缓冲区joyce尚未与文件关联。因此,如果您退出 Emacs,编辑器不会询问您是否要保存它。
This procedure isn't all that different from using
C-x C-f; about the only difference
is that the new buffer, joyce,
isn't yet associated with a file. Therefore, if you
quit Emacs, the editor won't ask you whether or not
you want to save it.
如果您不知道正在使用的文件的名称,则Cx b特别有用。假设您正在使用一些具有不寻常名称的不起眼文件,例如 .saves-5175-pcp832913pcs.nrockv01.ky.roadrunner.com。现在假设您不小心做了一些事情,导致该缓冲区从屏幕上消失。如何将 .saves-5175-pcp832913pcs.nrockv01.ky.roadrunner.com 重新显示到屏幕上?您需要记住整个名称还是部分名称?不需要。在执行其他操作之前,只需输入Cx b即可。默认缓冲区是最近消失的缓冲区;输入Enter,您将再次看到它。
C-x b is especially useful if you don't know the name of the file you are working with. Assume you're working with some obscure file with an unusual name such as .saves-5175-pcp832913pcs.nrockv01.ky.roadrunner.com. Now assume that you accidentally do something that makes this buffer disappear from your screen. How do you get .saves-5175-pcp832913pcs.nrockv01.ky.roadrunner.com back onto the screen? Do you need to remember the entire name or even a part of it? No. Before doing anything else, just type C-x b. The default buffer is the buffer that most recently disappeared; type Enter and you'll see it again.
或者,弹出缓冲区菜单 按主要模式列出缓冲区,您可以选择一种。按住Ctrl并单击鼠标左键可查看当前缓冲区的弹出菜单。 (屏幕顶部的缓冲区菜单还显示所有当前缓冲区。)
Alternatively, the Buffer Menu popup lists buffers by major mode, and you can choose one. Hold down Ctrl and click the left mouse button to see a pop-up menu of your current buffers. (The Buffers menu at the top of the screen also shows all current buffers.)
|
按住Ctrl 键并单击鼠标左键。 Hold down Ctrl and click the left mouse button. |
|
|
|
Emacs 按模式显示当前缓冲区的弹出菜单 (Mac OS X)。 Emacs displays a pop-up menu of current buffers by mode (Mac OS X). |
要循环遍历所有缓冲区,您 有,键入Cx → 转到下一个缓冲区(在缓冲区列表中)或键入Cx 转到上一个缓冲区。 (不要在按下箭头键的同时按住 Ctrl,否则 Emacs 会发出不愉快的蜂鸣声。)
To cycle through all the buffers you have, type C-x → to go to the next buffer (in the buffer list) or C-x to go to the previous buffer. (Don't hold down Ctrl while you press the arrow key or Emacs beeps unhappily.)
创建缓冲区很容易,只需 当您需要时,可以轻松删除它们。如果您觉得 Emacs 会话因太多缓冲区而变得混乱,您可能需要删除缓冲区。也许您开始使用一组五个缓冲区,现在想对另外五个缓冲区进行一些操作。摆脱第一组缓冲区可以让事情变得更容易一些。删除缓冲区也是一种有用的紧急逃生方法。例如,某些更换操作可能会产生灾难性的结果。您可以终止缓冲区并选择不保存更改,然后再次读取文件。
It's easy to create buffers, and just as easy to delete them when you want to. You may want to delete buffers if you feel your Emacs session is getting cluttered with too many buffers. Perhaps you started out working on a set of five buffers and now want to do something with another five. Getting rid of the first set of buffers makes it a bit easier to keep things straight. Deleting a buffer can also be a useful emergency escape. For example, some replacement operation may have had disastrous results. You can kill the buffer and choose not to save the changes, then read the file again.
删除缓冲区不会删除基础文件,也不同于不显示缓冲区。未显示的缓冲区仍然处于活动状态,而删除的缓冲区不再是 Emacs 会话的一部分。使用堆栈页面的类比,删除缓冲区就像从您正在编辑的当前缓冲区堆栈中取出一页并将其归档。
Deleting a buffer doesn't delete the underlying file nor is it the same as not displaying a buffer. Buffers that are not displayed are still active whereas deleted buffers are no longer part of your Emacs session. Using the analogy of a stack of pages, deleting a buffer is like taking a page out of the current stack of buffers you are editing and filing it away.
删除缓冲区也不会让您面临丢失更改的风险。如果您更改了缓冲区(并且该缓冲区与文件关联),Emacs 会在删除缓冲区之前询问您是否要保存更改。您将丢失对未连接到文件的任何缓冲区的更改,但您可能不关心这些缓冲区。
Deleting buffers doesn't put you at risk of losing changes, either. If you've changed the buffer (and the buffer is associated with a file), Emacs asks if you want to save your changes before the buffer is deleted. You will lose changes to any buffers that aren't connected to files, but you probably don't care about these buffers.
删除缓冲区是一个基本操作,它位于 Emacs 工具栏上,即 X 符号。现在让我们学习如何通过键盘来提高 Emacs 的流畅度。
Deleting a buffer is such a basic operation that it is on the Emacs toolbar, the X symbol. Now let's learn how to do it from the keyboard to increase your fluency in Emacs.
要删除缓冲区,请键入Cx k(表示 kill-buffer)。 Emacs 显示当前显示的缓冲区的名称;按Enter将其删除,或者如果显示的缓冲区名称不是您要删除的缓冲区名称,请输入另一个缓冲区名称,然后按Enter。如果您进行了更改但尚未保存,Emacs 将显示以下消息:
To delete a buffer, type C-x k (for kill-buffer). Emacs shows the name of the buffer currently displayed; press Enter to delete it or type another buffer name if the one being displayed is not the one you want to delete, then press Enter. If you've made changes that you haven't yet saved, Emacs displays the following message:
缓冲区buffer name 已修改。还是杀? (是还是不是)。Buffer buffer name modified. Kill anyway? (yes or no).要放弃更改,请输入yes,Emacs 就会终止缓冲区。要停止缓冲区删除过程,请键入 no。然后,您可以键入Cx Cs来保存缓冲区,然后键入 Cx k来终止它。
To ditch your changes, type yes, and Emacs kills the buffer. To stop the buffer deletion process, type no. You can then type C-x C-s to save the buffer, followed by C-x k to kill it.
您还可以让 Emacs 询问您是否删除每个缓冲区,您可以决定是否单独删除每个缓冲区。键入Mx Kill-some-buffers以这种方式清除不需要的缓冲区。 Emacs 显示每个缓冲区的名称以及它是否被修改,然后询问您是否要终止它。 Emacs 提供杀死每个缓冲区的功能,包括它自动创建的缓冲区,例如*scratch*和
*Messages*。如果您杀死会话中的所有缓冲区,Emacs 会创建一个新*scratch*缓冲区;毕竟,屏幕上必须显示一些内容!
You can also have Emacs ask you about deleting each buffer, and you
can decide whether to kill each one individually. Type M-x kill-some-buffers to weed out unneeded
buffers this way. Emacs displays the name of each buffer and whether
or not it was modified, then asks whether you want to kill it. Emacs
offers to kill each and every buffer, including the buffers it
creates automatically, like *scratch* and
*Messages*. If you kill all the buffers in your
session, Emacs creates a new *scratch* buffer;
after all, something has to display on the screen!
窗口是屏幕上的区域 Emacs 显示您正在编辑的缓冲区。您可以同时在屏幕上显示多个窗口,每个窗口显示不同的缓冲区或同一缓冲区的不同部分。当然,窗户越多,每个窗户就越小;与 GUI 窗口不同,Emacs 窗口不能重叠,因此当您添加更多窗口时,旧窗口会缩小。屏幕就像一个馅饼;你可以把它切成很多块,但是你切的块越多,它们就必须越小。您可以将窗口并排放置,一个放在另一个顶部,或者将它们混合放置。每个窗口都有自己的模式行,用于标识缓冲区名称、正在运行的模式以及缓冲区中的位置。为了清楚地表明一个窗口的开始位置和另一个窗口的结束位置,模式线通常带有阴影。
Windows are areas on the screen in which Emacs displays the buffers that you are editing. You can have multiple windows on the screen at one time, each displaying a different buffer or different parts of the same buffer. Granted, the more windows you have, the smaller each one is; unlike GUI windows, Emacs windows can't overlap, so as you add more windows, the older ones shrink. The screen is like a pie; you can cut it into many pieces, but the more pieces you cut, the smaller they have to be. You can place windows side-by-side, one on top of the other, or mix them. Each window has its own mode line that identifies the buffer name, the modes you're running, and your position in the buffer. To make it clear where one window begins and another ends, mode lines are usually shaded.
正如我们所说,窗口不是缓冲区。事实上,同一缓冲区上可以有多个窗口。如果您想同时查看大文件的不同部分,这样做通常很有帮助。您甚至可以在两个窗口中显示缓冲区的相同部分,并且在一个窗口中所做的任何更改都会反映在另一个窗口中。
As we've said, windows are not buffers. In fact, you can have more than one window on the same buffer. Doing so is often helpful if you want to look at different parts of a large file simultaneously. You can even have the same part of the buffer displayed in two windows, and any change you make in one window is reflected in the other.
当您考虑标记、剪切和粘贴文本时,缓冲区和窗口之间的区别变得很重要。标记与缓冲区相关联,而不是与窗口相关联,并且每个缓冲区只能有 一标记。如果您转到同一缓冲区上的另一个窗口并设置标记,Emacs 会将标记移动到新位置,而忘记上次设置的位置。
The difference between buffers and windows becomes important when you think about marking, cutting, and pasting text. Marks are associated with buffers, not with windows, and each buffer can have only one mark. If you go to another window on the same buffer and set the mark, Emacs moves the mark to the new location, forgetting the place you set it last.
至于游标,你只有 一个光标,光标的位置决定活动窗口。然而,虽然一次只有一个光标,但每个窗口确实单独跟踪您当前的编辑位置,也就是说,您可以将光标从一个窗口移动到另一个窗口,进行一些编辑,跳回第一个窗口,然后在同一个地方。窗口对当前位置(无论光标是否在窗口中)的概念称为 点。每个窗口都有自己的点。互换使用术语“点”和“光标”很容易 ,但我们会尽量具体化。
As for cursors, you have only one cursor, and the cursor's location determines the active window. However, although there is only one cursor at a time, each window does keep track of your current editing location separately—that is, you can move the cursor from one window to another, do some editing, jump back to the first window, and be in the same place. A window's notion of your current position (whether or not the cursor is in the window) is called the point. Each window has its own point. It's easy to use the terms point and cursor interchangeably—but we'll try to be specific.
您可以创建水平窗口或垂直窗口或两者都创建,但就我个人而言,我们将垂直窗口与更高级的深奥内容放在本章末尾附近。在这里,我们将讨论创建水平窗口、在新窗口中查找文件以及删除窗口。
You can create horizontal windows or vertical windows or both, but personally we place vertical windows with the more advanced esoterica near the end of the chapter. Here we'll discuss creating horizontal windows, finding a file in a new window, and deleting windows.
最常用的 窗口命令是Cx 2(用于垂直分割窗口)。该命令将当前窗口分成两个水平方向的窗口。您可以重复此命令将屏幕分割成更多水平窗口。
The most commonly used window command is C-x 2 (for split-window-vertically). This command splits the current window into two, horizontally oriented windows. You can repeat this command to split the screen into more horizontal windows.
|
类型:CX 2 Type: C-x 2 |
|
|
|
屏幕分为两个水平窗口;模式线划分每个窗口。 The screen is divided into two horizontal windows; the mode line demarcates each window. |
你也可以有 Emacs 设置 当您开始会话时为您显示窗口。如果要在水平窗口中编辑两个文件,请在命令提示符下启动 Emacs 时指定它们的文件名。例如,如果您想编辑 dickens和Joyce,您可以输入emacs dickens Joyce,Emacs 会在两个水平窗口中显示这些文件。如果您尝试使用两个以上的文件,Emacs 将显示两个水平窗口,其中一个窗口中包含一个文件,另一个窗口中包含一系列缓冲区。
You can also have Emacs set up windows for you when you start a session. If you want to edit two files in horizontal windows, specify their filenames when you start Emacs at a command prompt. For example, if you wanted to edit dickens and joyce, you would type emacs dickens joyce and Emacs would display these files in two horizontal windows. If you try this with more than two files, Emacs displays two horizontal windows, with a file in one and a list of buffers in the other.
许多“其他窗口”命令只是普通命令, 其中插入了4 。例如,要在另一个窗口中查找文件,请键入Cx 4 f。 (如果当前仅打开一个窗口,Emacs 将打开另一个窗口。)要在另一个窗口中选择不同的缓冲区,请键入Cx 4 b。许多用户发现这些命令比普通的 Cx Cf和Cx b命令更好,因为它们节省了您一个步骤:您不需要移动到窗口,发出命令,然后返回。
A number of the "other window" commands are just the ordinary command with a 4 inserted in it. For example, to find a file in another window, type C-x 4 f. (If only one window is currently open, Emacs opens another one.) To select a different buffer in another window, type C-x 4 b. Many users find these commands preferable to the normal C-x C-f and C-x b commands because they save you a step: you need not move to the window, give a command, and move back.
打开多个窗口后,能够滚动它们而无需移动到那里会很有帮助。要滚动另一个窗口,请键入CMv。
Once you've got multiple windows open, it's helpful to be able to scroll them without moving there. To scroll the other window, type C-M-v.
从一个窗口移动到 另一个,键入Cx o(o在此命令中 代表other )。如果显示两个以上的窗口,Emacs 会从一个窗口移动到下一个窗口。无法指定要移动到哪个窗口,因此如果显示两个以上的窗口,您可能需要多次键入Cx o才能到达所需的窗口。 (如果您使用的是 GUI 版本,也可以在窗口中单击鼠标。)
To move from one window to another, type C-x o (o stands for other in this command). If you have more than two windows displayed, Emacs moves from one to the next. There's no way to specify which window to move to, so you may have to type C-x o a few times to get to the one you want if you have more than two windows displayed. (You can also click your mouse in a window if you're using the GUI version.)
现在您可以创建窗口并可以在它们之间移动,您还能做什么?几乎任何东西。我们在 迪肯斯的两扇窗户都开着,一扇在另一扇的上面。最初,这两个窗口都在查看同一个文件。
Now that you can create windows and can move between them, what else can you do? Practically anything. With our two windows on dickens open, one on top of the other. Initially, both of these windows are looking at the same file.
我们可以在任一窗口中给出我们想要的任何编辑命令。我们可以在一个窗口中来回移动而不影响另一个窗口。让我们看看如果我们想编辑另一个文件会发生什么。
We can give any editing commands we want within either window. We can move back and forth in one window without affecting the other. Let's see what happens if we want to edit another file.
|
类型:Cx Cf 布莱克 Type: C-x C-f blake |
|
|
|
现在您有两个窗口、两个缓冲区和两个文件。 Now you have two windows, two buffers, and two files. |
通过使用Cx o,我们可以编辑一个文件,然后编辑另一个文件。我们可以从一个缓冲区中删除文本并将其拉回到另一个缓冲区中。例如,让我们将布莱克诗的第一行移到缓冲区的顶部
dickens。
By using C-x o, we can edit one file
and then the other. We can kill text from one buffer and yank it back
in another. For example, let's move the first line
of Blake's poem to the top of the
dickens buffer.
|
类型:Ck Ck Cx o M-< Cy Enter Type: C-k C-k C-x o M-< C-y Enter |
|
|
|
布莱克文本已被拉入 The Blake text has been yanked into the |
使用多个缓冲区进行编辑 例如,如果您想要将材料从一个文件复制到另一个文件,或者如果您想要在编辑另一个文件时读取包含参考材料的文件,则单独的窗口特别有用。程序员经常需要同时查看多个不同的文件,例如头文件和代码文件,或者函数调用站点和正在调用的例程。一旦您习惯了在不同窗口之间移动的命令,您可能会将大部分时间花在屏幕上的两个或三个窗口上。
Editing with multiple buffers in separate windows is particularly useful if, for example, you want to copy material from one file to another or if you want to read a file containing reference material while editing another. Programmers often need to look at several different files at the same time—for example, a header file and a code file, or a function call site and the routine that's being called. Once you get used to the commands for moving between different windows, you may spend most of your time with two or three windows on your screen.
删除一个窗口仅仅意味着
它不再显示;它不会删除任何信息或任何未保存的更改。底层缓冲区仍然存在,您可以使用
Cx b切换到它。要删除您所在的窗口,请键入Cx 0(零)。如果您想删除除您正在处理的窗口之外的所有窗口,请键入Cx 1(一),意思是“将此窗口设为我唯一的窗口”。正如您所期望的,剩余的窗口会“增长”以填满剩余的空间。您还可以通过键入以下内容删除特定缓冲区上的所有窗口:Mx delete-windows-on Enter
Enter。buffername
Deleting a window only means that
it
isn't displayed anymore; it doesn't
delete any of the information or any of your unsaved changes. The
underlying buffer is still there, and you can switch to it using
C-x b. To delete the window
you're in, type C-x
0 (zero). If you want to delete all windows but the one
you're working on, type C-x
1 (one), meaning "make this my one and
only window." As you'd expect, the
remaining window "grows" to fill up
the rest of the space. You can also delete all windows on a certain
buffer by typing: M-x delete-windows-on Enter
buffername
Enter.
现在您已经知道 Emacs 将 GUI 窗口称为“框架”。在本节中,我们将介绍如何创建框架、在框架之间导航以及删除框架。
By now you know that Emacs calls GUI windows "frames." In this section, we'll cover how to create frames, navigate between frames, and delete frames.
要打开一个新框架, 类型 Cx 5 2(用于make-frame)。 Emacs 创建一个包含当前缓冲区的新框架,并将其放在当前框架的顶部。
To open a new frame, type C-x 5 2 (for make-frame). Emacs makes a new frame containing the current buffer and puts it on top of the current frame.
如果您的新框架与当前框架完全重叠,您可能需要调整新框架的大小以告诉他们 分开。要获得更方便的解决方案,请将这些行添加到您的 .emacs文件中:
If your new frame completely overlaps your current frame, you may need to size the new frame to tell them apart. For a more convenient solution, add these lines to your .emacs file:
(setq 初始帧列表 '((顶部 . 10) (左侧 . 30)
(宽度.90)(高度.50)))
(setq 默认框架列表 '((宽度 . 80) (高度 . 45)))(setq initial-frame-alist '((top . 10) (left . 30)
(width . 90) (height . 50)))
(setq default-frame-alist '((width . 80) (height . 45)))这些行设置 Emacs 框架的宽度和高度的大小。第一帧是在initial-frame-alist中设置的大小(在本例中,宽90个字符,高50行,顶部和左侧定义一个插图),由default-frame-alist指定的后续帧将为80个字符宽,45 行高。根据您的显示器,您可以使这些数字更小或更大。
These lines set up sizes for the width and height of Emacs frames. The first frame is the size set in initial-frame-alist (in this example, 90 characters wide by 50 lines high with top and left defining an inset), and subsequent frames, specified by default-frame-alist, will be 80 characters wide and 45 lines high. Depending on your display, you can make these numbers smaller or larger.
在这里,我们编辑了亨利·詹姆斯的一些内容。
Here we edit a bit of Henry James.
假设我们想在
dickens缓冲区上打开一个帧。
Let's say we want to open a frame on our
dickens buffer.
|
类型:Cx 5 f 狄更斯 输入 Type: C-x 5 f dickens Enter |
|
|
|
Emacs 在 上打开一个新框架 Emacs opens a new frame on |
如果您键入Cx b移动到另一个缓冲区,框架顶部的名称将更改为新缓冲区的名称(在 Linux 上,它还会显示路径)。要移动到缓冲区并将其放入新帧中,请键入Cx 5 b。你可能已经猜到了。
If you type C-x b to move to another buffer, the name at the top of the frame changes to the new buffer's name (and on Linux, it shows the path as well). To move to a buffer and put it in a new frame, type C-x 5 b. You might have guessed that one.
您可以在帧之间移动 在几个方面。您可以使用鼠标选择一个帧或按Cx 5 o转到另一个帧。要查看当前帧的列表,请 从“缓冲区”菜单中选择“帧”。 (如果只有一帧,则 “帧”选项不会出现在此菜单上。)
You can move between frames in several ways. You can use the mouse to select a frame or press C-x 5 o to go to another frame. To see a list of current frames, select Frames from the Buffers menu. (If you have only one frame, the Frames option does not appear on this menu.)
要删除框架,请按Cx 5 0。 Emacs 删除 您所在的框架。删除框架与删除窗口一样,仅影响显示。底层缓冲区仍然处于活动状态,您可以通过键入Cx b移动到它。
To get rid of a frame, press C-x 5 0. Emacs deletes the frame you are in. Deleting a frame, like deleting a window, affects only the display. The underlying buffer is still active, and you can move to it by typing C-x b.
如果您尝试使用Cx 5 0删除仅剩下的框架,Emacs 将不会执行此操作。要退出 Emacs,请键入Cx Cc或关闭框架,就像使用鼠标关闭任何其他 GUI 窗口一样。
If you try to use C-x 5 0 to delete the only frame that is left, Emacs won't do it. To exit Emacs, type C-x C-c or close the frame as you would any other GUI window using the mouse.
要最小化框架,请以通常的方式最小化它或按 Cz。表 4-1 总结了帧命令。
To minimize a frame, either minimize it in the usual way or press C-z. Table 4-1 summarizes the frame commands.
表 4-1。帧命令
Table 4-1. Frame commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
Cx 5 o 缓冲区 → 帧 C-x 5 o Buffers → Frames |
其他框架 other-frame |
移至其他框架。 Move to other frame. |
|
Cx 5 0 文件 → 删除帧 C-x 5 0 File → Delete Frame |
删除帧 delete-frame |
删除当前帧。 Delete current frame. |
|
Cx 5 2 文件 → 新框架 C-x 5 2 File → New Frame |
制作框架 make-frame |
在当前缓冲区上创建一个新帧。 Create a new frame on the current buffer. |
|
CX 5 f C-x 5 f |
查找文件其他框架 find-file-other-frame |
在新框架中查找文件。 Find file in a new frame. |
|
CX 5 r C-x 5 r |
查找文件只读其他框架 find-file-read-only-other-frame |
在新框架中查找文件,但该文件是只读的。 Finds a file in a new frame, but it is read-only. |
|
CX 5 b C-x 5 b |
切换到缓冲区其他帧 switch-to-buffer-other-frame |
制作框架并在其中显示其他缓冲区。 Make frame and display other buffer in it. |
在本节中,我们将了解如何保存多个缓冲区、重命名缓冲区、只读缓冲区以及可以对缓冲区列表执行的操作——这不仅是一个有用的工具,而且很好地介绍了您将在目录中遇到的原理编辑 Dired,在第 5 章中介绍。
In this section, we'll learn about saving multiple buffers, renaming buffers, read-only buffers, and operations you can do with the buffer list—not only a useful tool but a good introduction to the principles you'll encounter in the directory editor, Dired, covered in Chapter 5.
你知道如何保存缓冲区 单独输入Cx Cs。一旦您使用多个缓冲区,您还应该知道可以通过键入Cx s(用于save-some-buffers)一次性保存所有缓冲区。 Emacs 询问您是否要保存与文件连接的每个缓冲区(它不会保存您创建的但尚未与文件关联的新缓冲区,当然,它不会保存其自己的内部缓冲区)缓冲区)。对于每个缓冲区,您可以回答y保存它或n不保存。您还可以打字!无需询问即可保存所有缓冲区。如果您只想保存此缓冲区,请键入句点 (.)。如果您想取消命令并且不保存当前缓冲区,请按q(当然,您在按q之前保存的任何缓冲区都已保存;q不会撤消这些缓冲区)。在决定是否保存之前,您可能需要查看缓冲区;如果是这样,请输入 Cr。 Emacs 进入查看模式,允许您查看缓冲区但不能进行更改。按 q退出查看模式并继续保存缓冲区。
You know about saving buffers individually by typing C-x C-s. Once you're using multiple buffers, you should also know that you can save them all at once by typing C-x s (for save-some-buffers). Emacs asks you if you want to save each buffer that is connected with a file (it doesn't offer to save new buffers you've created but have not associated with a file and, of course, it doesn't save its own internal buffers). For each buffer, you can answer y to save it or n not to. You can also type ! to save all the buffers without asking. If you want to save this buffer and no more, type a period (.). If you want to cancel the command and not save the current buffer, press q (of course, any buffers you saved before pressing q are already saved; q does not undo those). You may want to look at the buffer before deciding whether to save it; if so, type C-r. Emacs enters view mode, allowing you to look at the buffer but not make changes. Press q to exit view mode and continue saving buffers.
当您编辑文件时, 缓冲区采用文件名。如果文件名很长,您可能会发现将缓冲区重命名为较短的名称很方便(此重命名不会影响文件名,只会影响缓冲区名称)。此功能在不提供良好补全功能的 Emacs 版本上最有用;在 GNU Emacs 中,每当您需要输入缓冲区名称时,只需输入前几个唯一字母,然后按Tab键即可让 Emacs 为您补全名称。在某些情况下,您可能需要重命名缓冲区。
When you are editing a file, the buffer takes on the name of the file. If you have long filenames, you may find it convenient to rename buffers to shorter names (this renaming doesn't affect the filename, just the buffer name). This feature is mostly useful on versions of Emacs that don't offer good completion capabilities; in GNU Emacs, whenever you have to type a buffer name, you just type the first few unique letters and press Tab to have Emacs complete the name for you. In some circumstances, you may want to rename buffers.
要重命名缓冲区,请输入Mx rename-buffer。 Emacs 要求输入新名称;键入它并按Enter。新名称显示在模式行上。重命名缓冲区在 shell 模式下特别方便,如第 5 章所述。您启动一个命令 shell,然后重命名缓冲区并启动另一个命令 shell,这样就可以同时运行尽可能多的 shell。
To rename a buffer, type M-x rename-buffer. Emacs asks for the new name; type it and press Enter. The new name is displayed on the mode line. Renaming buffers comes in particularly handy in shell mode, described in Chapter 5. You start one command shell, and then rename the buffer and start another, in this way running as many shells as you have use for simultaneously.
如前所述,在 GNU Emacs 中,模式行上仅显示缓冲区名称,而不是缓冲区名称 和文件名。即使您重命名包含文件的缓冲区,Emacs 也会记住缓冲区和文件之间的连接,您可以在保存文件 ( Cx Cs ) 或显示缓冲区列表(本章稍后介绍)时看到该连接。
As mentioned earlier, in GNU Emacs only the buffer name is displayed on the mode line, rather than the buffer name and the filename. Even if you rename a buffer that contains a file, Emacs remembers the connection between buffer and file, which you can see if you save the file (C-x C-s) or display the buffer list (described later in the chapter).
如果你有两个缓冲区怎么办
同名?假设您正在编辑主目录中
一个名为“outline”的文件,以及一个子目录中名为“outline”的另一个文件。两个缓冲区都称为outline,但 Emacs 通过附加<2>第二个缓冲区的名称来区分它们。 (您可以通过查看缓冲区列表来区分哪个是哪个,这将在本章后面讨论。)在这种情况下,Emacs 提供了一个将目录添加到缓冲区的选项:从“选项”菜单中选择“在缓冲区名称中使用目录”。假设您已打开此选项并正在编辑一个名为.localized的文件; Emacs 将简单地调用此缓冲区.localized。现在您可以从子目录中找到第二个同名文件。 Emacs不调用此缓冲区.localized<2>,而是命名缓冲区
目录
/.localized,让您一眼就能轻松区分缓冲区。此选项有一些限制。它仅显示父目录,而不显示完整路径,并且仅当多个缓冲区具有相同名称时才显示目录名称。我们希望它能更进一步,提供在所有缓冲区的模式行上包含目录的选项。
What if you have two buffers
with the same name? Let's
say you are editing a file called outline from
your home directory and another file called
outline from one of your subdirectories. Both
buffers are called outline, but Emacs
differentiates them by appending <2> to the
name of the second buffer. (You can tell which is which by looking at
the buffer list, discussed later in this chapter.) Emacs offers an
option that adds a directory to buffers in this situation: select Use
Directory in Buffer Names from the Options menu.
Let's say you've turned on this
option and are editing a file called .localized;
Emacs will call this buffer simply .localized. Now
you find a second file of the same name from a subdirectory. Instead
of calling this buffer .localized<2>, Emacs
names the buffer
directory
/.localized, making
it easy for you to tell the buffers apart at a glance. This option
has some limitations. It shows only the parent directory, not the
full path, and it shows directory names only if multiple buffers have
the same name. We wish it would go a bit further and provide the
option of including the directory on the mode line for all buffers.
一句建议:如果您有很多名为
proposal、proposal
<2>、
proposal<3>等名称的缓冲区,那么当您请求文件时,您可能会忘记编辑目录。如果您尝试查找文件但目录错误,Emacs 会假定您想要开始一个新文件。例如,假设您想要编辑文件~/work/proposal,但改为请求文件~/novel/proposal。由于
~/novel/proposal不存在,Emacs 创建一个名为 的新的空缓冲区proposal。如果您纠正了错误(Cx Cf ~/work/proposal),Emacs 会相应地重命名您的缓冲区:您的空缓冲区与~/novel/proposalproposal相关联
;您想要的缓冲区名为
.proposal<2>
One word of advice: if you have a lot of buffers with names like
proposal, proposal
<2>, and
proposal<3> around, you're
probably forgetting to edit the directory when you ask for a file. If
you try to find a file but get the directory wrong, Emacs assumes you
want to start a new file. For example, let's say you
want to edit the file ~/work/proposal, but
instead ask for the file ~/novel/proposal. Since
~/novel/proposal doesn't exist,
Emacs creates a new, empty buffer named proposal.
If you correct your mistake (C-x C-f
~/work/proposal), Emacs renames your buffers accordingly:
your empty buffer proposal is associated with
~/novel/proposal; the buffer you want is named
proposal<2>.
以下是处理查找错误文件这一常见错误的提示。如果您发现使用Cx Cf找到了错误的文件,请使用Cx Cv将其替换为您想要的文件。Cx Cv找到一个文件,但不是创建新的缓冲区,而是替换当前缓冲区中的文件。它的意思是“给我一份我真正想要找到的文件,而不是这个文件。”使用此命令可以避免存在不必要的编号缓冲区(即proposal、proposal<2>等)的问题
。
Here's a hint for dealing with the very common
mistake of finding the wrong file. If you notice that
you've found the wrong file with C-x C-f, use C-x
C-v to replace it with the one you want. C-x C-v finds a file, but instead of making a
new buffer, it replaces the file in the current buffer. It means
"get me the file I really meant to find instead of
this one." Using this command circumvents the
problem of having unnecessary numbered buffers (i.e.,
proposal, proposal<2>,
and so on) lying around.
当你工作的时候, 您可能需要读取一些您不想更改的文件:您只想浏览它并查看其内容。当然,很容易误触键盘,进行虚假修改。我们已经讨论了几种恢复原始文件的方法,但最好完全防止这种情况发生。如何?
While you're working, you may need to read some file that you don't want to change: you just want to browse through it and look at its contents. Of course, it is easy to touch the keyboard accidentally and make spurious modifications. We've discussed several ways to restore the original file, but it would be better to prevent this from happening at all. How?
您可以通过按Cx Cq将任何缓冲区设为只读。在练习缓冲区上尝试一下,您会注意到
两个百分号 ( %%) 出现在模式行的左侧,与
**如果您更改了缓冲区,则会出现星号 ( )。百分号表示该缓冲区是只读的。[ 1 ]如果您尝试在只读缓冲区中输入内容,Emacs 只会向您发出蜂鸣声,并Buffer is read-only在迷你缓冲区中显示一条错误消息 ( )。当您改变主意并想要再次开始编辑只读缓冲区时会发生什么?只需再次输入Cx Cq即可。该命令切换缓冲区的只读状态,也就是说,重复键入
Cx Cq会使缓冲区在只读和读写之间交替。
You can make any buffer read-only by pressing C-x C-q. Try this on a practice buffer and
you'll notice that
two percent signs
(%%) appear on the left side of the mode line, in
the same place where
asterisks (**)
appear if you've changed a buffer. The percent signs
indicate that the buffer is read-only.[1] If
you try to type in a read-only buffer, Emacs just beeps at you and
displays an error message (Buffer is read-only) in
the minibuffer. What happens when you change your mind and want to
start editing the read-only buffer again? Just type C-x C-q again. This command toggles the
buffer's read-only status—that is, typing
C-x C-q repeatedly makes the buffer
alternate between read-only and read-write.
当然,切换只读 status 不会更改文件的权限。如果您正在编辑包含其他人的文件的缓冲区,Cx Cq不会更改只读状态。编辑其他人的文件的一种方法是使用write-file命令制作您自己的文件的副本,然后进行更改。假设您想要更改其他人拥有的提案。读取文件,使用Cx Cw将文件写入您拥有的文件,然后按Cx Cq将其从只读状态更改为可写状态。当然,这些都不会修改原始文件;它只是为您提供了一份可供使用的副本。如果要将少量文本从只读文件移动到另一个文件,可以标记文本,然后按Mw进行复制。移动到要放置文本的位置,然后按Cy粘贴它。
Of course, toggling read-only status doesn't change the permissions on a file. If you are editing a buffer containing someone else's file, C-x C-q does not change the read-only status. One way to edit someone else's file is to make a copy of your own using the write-file command, and then make changes. Let's say you want to change a proposal that is owned by someone else. Read the file, write the file as one you own using C-x C-w, then change it from read-only to writable status by pressing C-x C-q. None of this, of course, modifies the original file; it just gives you a copy to work with. If you want to move a minor amount of text from a read-only file to another, you can mark the text then press M-w to copy it. Move to the place you want to put the text and press C-y to paste it.
您可以通过键入Cx 4 r在新窗口中以只读方式打开文件,或者通过键入Cx 5 r在新框架中以只读方式打开文件。这是众多命令之一,其中4表示窗口, 5表示框架。
You can open a file as read-only in a new window by typing C-x 4 r or in a new frame by typing C-x 5 r. This is one of a number of commands in which 4 means window and 5 means frame.
因为你可以创造无限 Emacs 会话中的缓冲区数量,您可能有太多的缓冲区,以至于您无法记住它们。在任何时候,您都可以获得缓冲区列表(是的,我们知道您知道如何通过按住Ctrl并单击鼠标左键来做到这一点,但这有点不同)。此列表为您提供重要信息,例如,自上次保存缓冲区以来是否更改了缓冲区。
Because you can create an unlimited number of buffers in an Emacs session, you can have so many buffers going that you can't remember them all. At any point, you can get a list of your buffers (yes, we know you know how to do that by holding down Ctrl and clicking the left mouse button, but this is a little different). This list provides you with important information—for example, whether you've changed the buffer since you last saved it.
如果您按Cx Cb,Emacs 会列出您的缓冲区。它*Buffer List*
在屏幕上创建一个新窗口,其中显示所有缓冲区。
If you press C-x C-b, Emacs lists
your buffers. It creates a new *Buffer List*
window on the screen, which shows you all the buffers.
您可以使用此列表作为信息显示(“这些是我的缓冲区”),或者您可以实际使用此列表中的缓冲区,如 下一节将介绍。
You can use this list as an informational display ("these are my buffers") or you can actually work with buffers from this list, as covered in the next section.
图 4-3显示了缓冲区列表中每个符号的含义。
Figure 4-3 shows what each of the symbols in the buffer list means.
缓冲区列表不仅仅是一个显示。从缓冲区列表中,您可以显示、删除和保存缓冲区。移动到缓冲区 列表窗口,输入Cx o。 Emacs 将光标置于第一列。对于特定缓冲区,按n 或Cn向下移动一行,或按p或Cp向上移动一行。您还可以按 Space向下移动到下一行,按Del向上移动。 (向上和向下箭头键也可以。)这一系列的向上和向下选择可能看起来令人困惑,但提供了多个绑定,可以轻松地向上和向下移动,而无需查阅像这本书这样的书。
The buffer list is more than a display. From the buffer list, you can display, delete, and save buffers. To move to the buffer list window, type C-x o. Emacs puts the cursor in the first column. For a particular buffer, press n or C-n to move down a line or p or C-p to move up a line. You can also press Space to move down to the next line and Del to move up. (The up and down arrow keys work, too.) This array of up and down choices may seem confusing, but multiple bindings are given to make it easy to move up and down without consulting a book like this one.
您可以使用一组单字符命令来处理列出的缓冲区。要删除缓冲区,请转到要删除的缓冲区所在的行并输入d或
k。该字母D
出现在第一列中。您可以根据需要标记任意多个要删除的缓冲区。缓冲区不会立即被删除;完成标记缓冲区后,按x(代表“执行”)将其删除。如果您要删除的任何缓冲区与文件连接,Emacs 会在执行任何操作之前询问您是否要保存更改。 (请注意,它不会询问您有关未与文件连接的缓冲区的信息,因此请务必在删除它们之前保存您想要的任何缓冲区。)
You use a set of one-character commands to work with the buffers that
are listed. To delete a buffer, go to the line for the buffer you
want to delete and type d or
k. The letter D
appears in the first column. You can mark as many buffers for
deletion as you want to. The buffers aren't deleted
immediately; when you're finished marking buffers,
press x (which stands for
"execute") to delete them. If any
of the buffers you want to delete are connected with files, Emacs
asks if you want to save the changes before doing anything. (Note
that it does not ask you about buffers that aren't
connected with files, so be sure to save any that you want before
deleting them.)
如果您在键入x之前改变主意要删除缓冲区 ,则可以通过转到相应的行并键入u来取消标记缓冲区。为了方便起见,Del键还会取消标记列表中的前一个缓冲区。你为什么要这样做?很简单:d会自动将您向下移动一行。如果您将文件标记为删除并立即改变主意,则可以按单个Del,而不是移至上一行并键入u取消标记)。
If you change your mind about deleting a buffer before typing x, you can unmark the buffer by going to the appropriate line and typing u. As a convenience, the Del key also unmarks the previous buffer in the list. Why would you do this? Simple: d automatically moves you down one line. If you mark a file for deletion and immediately change your mind, you can press a single Del rather than moving to the previous line and typing u for unmark).
要保存缓冲区,请转至以下行:
您要保存的缓冲区并按
s。该字母S
出现在第一列中。
当您确实想要保存缓冲区时按x 。因此,您可以查看缓冲区列表,选择要删除的缓冲区和要保存的缓冲区,然后键入x立即执行所有操作。同样,如果您改变主意,可以按u或Del取消保存。
To save a buffer, go to the line for
the buffer you want to save and press
s. The letter S
appears in the first column. Press x
when you really want to save the buffer. Therefore, you can look at
the buffer list, choose which buffers you want to delete and which
you want to save, and then type x to
do everything at once. Again, you can press u or Del to
cancel saves if you change your mind.
影响缓冲区的一条命令 当您键入时,它会立即显示波浪号 ( ~ )。键入~将缓冲区标记为未修改。实际上,这个符号告诉 Emacs 不要自动保存更改(因为缓冲区未修改,Emacs 没有理由使用其自动保存功能来保存更改)。当然,如果您进行了更改,则更改仍在缓冲区中;只是您本质上是在向 Emacs“撒谎”说没有进行任何更改。另外,如果您在将缓冲区标记为未修改后再次更改缓冲区,Emacs 会再次知道它已被修改并自动将其保存在备份文件中。备份文件名(并非巧合)的格式为filename~。
One command that affects a buffer immediately when you type it is tilde (~). Typing ~ marks a buffer as unmodified. In effect, this symbol tells Emacs not to save changes automatically (since the buffer is unmodified, Emacs has no reason to save changes with its auto-save feature). Of course, if you have made changes, the changes are still in the buffer; it's just that you're in essence "lying" to Emacs to say that no changes have been made. Also, if you change the buffer again after marking it unmodified, Emacs once again knows it has been modified and saves it automatically in a backup file. The backup filename (not coincidentally) has the format filename~.
您可以更改缓冲区的状态 读写变为只读,然后按%返回。按%会立即更改缓冲区的状态。当缓冲区为只读时,百分号出现在模式行上。当您进行编辑时,您可以通过按Cx Cq在读写和只读之间切换缓冲区,正如我们之前讨论的那样。
You can change a buffer's status from read-write to read-only and back again by pressing %. Pressing % changes the buffer's status immediately. Percentage signs appear on the mode line when a buffer is read-only. When you are editing, you can toggle a buffer between read-write and read-only by pressing C-x C-q, as we discussed earlier.
您还可以使用缓冲区列表在窗口中显示多个缓冲区。要全屏显示其中一个缓冲区,请将光标移至缓冲区列表窗口;使用Cn和Cp 移动到所需缓冲区的行,然后按1(数字一)。 Emacs 在全屏窗口中显示缓冲区。
You can also use the buffer list to display multiple buffers in windows. To display one of the buffers in a full screen, move the cursor into the buffer list's window; use C-n and C-p to move to the line for the buffer that you want, and press 1 (the number one). Emacs displays the buffer in a full-screen window.
如果要显示缓冲区之一来代替缓冲区列表,可以按f。要将缓冲区放入另一个窗口(即未被缓冲区列表占用的窗口)中,请键入o。 Emacs 在另一个窗口中显示缓冲区并将光标放在那里。 Press Co 的结果略有不同; Emacs 在另一个窗口中显示缓冲区,但不将光标放在那里。
If you want to display one of the buffers in place of the buffer list, you can press f. To put a buffer in another window (i.e., one not occupied by the buffer list), type o. Emacs displays the buffer in the other window and puts the cursor there. Pressing C-o has a slightly different result; Emacs displays the buffer in another window but doesn't put the cursor there.
剩下最后一个缓冲区显示命令。您可以要求 Emacs 显示多个缓冲区并让 Emacs 动态地为它们创建窗口。要选择要在窗口中显示的缓冲区,请按所需缓冲区旁边的m(表示 标记)。 Emacs在用m标记的缓冲区旁边显示一个>。要告诉 Emacs 显示您标记的缓冲区,请按v。 Emacs 使用水平窗口来显示您选择的缓冲区。
One final buffer display command remains. You can ask Emacs to display multiple buffers and have Emacs create windows for them dynamically. To select buffers to be displayed in windows, press m (for mark) next to the buffers you want. Emacs displays a > next to the buffers you mark with m. To tell Emacs to display the buffers you've marked, press v. Emacs makes horizontal windows to display the buffers you've chosen.
要删除该*Buffer List*窗口,
如果您在缓冲区列表窗口中,请键入Cx 0 ;如果您在另一个窗口中,请键入Cx 1(第一个)。表 4-2显示了缓冲区操作的摘要
命令。
To get rid of the *Buffer List* window, type
C-x 0 if you are in the buffer list
window or C-x 1 (the number one) if
you are in another window. Table 4-2 shows a
summary of buffer manipulation
commands.
表 4-2。缓冲区操作命令
Table 4-2. Buffer manipulation commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
Cx b 缓冲区 → 选择命名缓冲区 C-x b Buffers → Select Named Buffer |
切换到缓冲区 switch-to-buffer |
移动到指定的缓冲区。 Move to the buffer specified. |
|
Cx → 缓冲区 → 下一个缓冲区 C-x → Buffers → Next Buffer |
下一个缓冲区 next-buffer |
移动到缓冲区列表中的下一个缓冲区。 Move to the next buffer in the buffer list. |
|
Cx 缓冲区 → 上一个缓冲区 C-x Buffers → Previous Buffer |
前一个缓冲区 previous-buffer |
移动到缓冲区列表中的上一个缓冲区。 Move to the previous buffer in the buffer list. |
|
Cx Cb 缓冲区 → 列出所有缓冲区 C-x C-b Buffers → List All Buffers |
列表缓冲区 list-buffers |
显示缓冲区列表。 Display the buffer list. |
|
CXk C-x k |
终止缓冲区 kill-buffer |
删除指定的缓冲区。 Delete the buffer specified. |
|
(没有任何) (none) |
杀死一些缓冲区 kill-some-buffers |
询问删除每个缓冲区。 Ask about deleting each buffer. |
|
(没有任何) (none) |
重命名缓冲区 rename-buffer |
将缓冲区的名称更改为指定的名称。 Change the buffer's name to the name specified. |
|
CXs C-x s |
保存一些缓冲区 save-some-buffers |
询问是否要保存每个修改的缓冲区。 Ask whether you want to save each modified buffer. |
表 4-3总结了使用的命令 缓冲区列表。
Table 4-3 summarizes the commands for working with the buffer list.
表 4-3。缓冲区列表命令
Table 4-3. Buffer list commands
|
击键 Keystrokes |
行动 Action |
发生 Occurs |
|---|---|---|
|
Cn、 空格、 n或 C-n, Space, n, or |
移动到列表中的下一个缓冲区(即向下一行)。 Move to the next buffer in the list (i.e., down one line). |
立即地 Immediately |
|
CP、 p或 C-p, p, or |
移至列表中的前一个缓冲区(即向上一行)。 Move to the previous buffer in the list (i.e., up one line). |
立即地 Immediately |
|
d d |
将缓冲区标记为删除。 Mark buffer for deletion. |
当您按x When you press x |
|
k k |
将缓冲区标记为删除。 Mark buffer for deletion. |
当您按x When you press x |
|
s s |
保存缓冲区。 Save buffer. |
当您按x When you press x |
|
你 u |
取消标记缓冲区。 Unmark buffer. |
立即地 Immediately |
|
X x |
在所有标记的缓冲区上执行其他单字母命令。 Execute other one-letter commands on all marked buffers. |
立即地 Immediately |
|
德尔 Del |
取消标记列表中的前一个缓冲区;如果没有标记,则向上移动一行。 Unmark the previous buffer in the list; if there is no mark, move up one line. |
立即地 Immediately |
|
~ ~ |
将缓冲区标记为未修改。 Mark buffer as unmodified. |
立即地 Immediately |
|
% % |
切换缓冲区的只读状态。 Toggle read-only status of buffer. |
立即地 Immediately |
|
1 1 |
全屏显示缓冲区。 Display buffer in a full screen. |
立即地 Immediately |
|
2 2 |
在水平窗口中显示此缓冲区和下一个缓冲区。 Display this buffer and the next one in horizontal windows. |
立即地 Immediately |
|
F f |
用该缓冲区替换缓冲区列表。 Replace buffer list with this buffer. |
立即地 Immediately |
|
哦 o |
用这个缓冲区替换其他窗口。 Replace other window with this buffer. |
立即地 Immediately |
|
米 m |
标记要在窗口中显示的缓冲区。 Mark buffers to be displayed in windows. |
当你按v When you press v |
|
v v |
显示缓冲区标记为m; Emacs 根据需要创建尽可能多的窗口。 Display buffers marked with m; Emacs makes as many windows as needed. |
立即地 Immediately |
|
q q |
退出缓冲区列表。 Quit buffer list. |
立即地 Immediately |
[ 1 ]**表示已更改且
%%表示只读的
规则的例外是*scratch*缓冲区。因为如果您终止缓冲区,Emacs 不会警告您
*scratch*,即使缓冲区已更改,它也会向您提供一些指示,表明有未保存的更改。%%缓冲区*scratch*放置%*在模式行上,而不是。
[1] The exception
to the rule that ** means changed and
%% means read-only is the
*scratch* buffer. Because Emacs
doesn't warn you if you kill the
*scratch* buffer, even if it is changed, it wants
to give you some indication that there are unsaved changes. Instead
of %%, the *scratch* buffer
puts %* on the mode line.
根据您的要求,除了水平窗口之外,您可能还希望使用并排窗口,或者使用并排窗口来代替水平窗口。为了更好地控制,您可能想知道如何调整窗口大小(并且因为它们不是 GUI 窗口,所以您无法使用鼠标执行此操作)。[ 2 ]您可能还想知道如何在窗口之间比较文件,这是基本文件比较的一个好功能。
Depending on your requirements, you may want to work with side-by-side windows in addition to or instead of horizontal windows. For finer control, you may want to know how to size windows (and because they're not GUI windows, you can't do that with the mouse).[2] You may also want to know how to compare files between windows, a good feature for basic file comparison.
分割窗口 垂直进入两个并排的窗口,输入Cx 3。您可以重复执行此步骤以创建更多并排窗口。
To split the window vertically into two side-by-side windows, type C-x 3. You can execute this step repeatedly to create more side-by-side windows.
当您创建多个垂直窗口时,Emacs 通常 没有足够的空间来显示整行文本。由于垂直窗口通常不会显示整行文本,因此行末尾的右箭头(在图形实现上)或美元符号(在基于终端的实现上)告诉您该行是继续的。
When you create multiple vertical windows, Emacs usually doesn't have enough room to display a full line of text. Because vertical windows don't usually show full lines of text, a right arrow (on graphical implementations) or a dollar sign (on terminal-based implementations) at the end of a line tells you the line is continued.
要查看该行的其余部分,您需要知道如何向左和向右滚动文本。要将当前显示的文本推到左侧(以便您可以看到右侧的内容),请输入 Cx <。窗口左侧显示向左箭头或美元符号,表示左侧有更多文本。要将显示的文本推到右侧(以便您可以看到左侧的内容),请键入 Cx >。每当您的某一行太宽时,您都可以使用这些命令,无论有或没有窗口都可能发生这种情况。
To see the rest of the line, you need to know how to scroll text to the left and right. To push the text currently being displayed to the left (so you can see what's on the right), type C-x <. Left arrows or dollar signs are displayed on the left side of the window to indicate that there is more text to the left. To push the text being displayed to the right (so you can see what's on the left), type C-x >. You can use these commands whenever one of your lines is too wide, which can happen with or without windows.
你如何在之间移动 视窗?正如我们之前提到的,Cx o将您移动到“下一个”窗口。但 Emacs 如何确定它是什么?
How do you move between windows? As we mentioned earlier, C-x o moves you to the "next" window. But how does Emacs determine what that is?
最好的表达方式是,Emacs 按照自然的阅读顺序在窗口中移动,从左到右,然后向下,再从左到右。在图 4-4中,缓冲区名称被编号以显示 Emacs 如何从一个窗口移动到下一个窗口。
The best way to express it is to say that Emacs moves through the windows in natural reading order, from left to right, then down, and again from left to right. In Figure 4-4, buffer names are numbered to show you how Emacs moves from one window to the next.
或者,您可以简单地使用鼠标选择所需的窗口。
Alternatively, you can simply select the window you want using the mouse.
Emacs 总是将窗口分成 两个相等的部分。这样的分割通常已经足够好了,但有时却并非如此,特别是当您成为窗户爱好者时。当屏幕上同时有四个、五个或六个窗口时,控制每个窗口的大小就变得很重要。否则,您最感兴趣的窗口最终会变得太小,当您只能看到文件中的五六行时,几乎不可能进行有用的编辑。如果您想让正在处理的窗口更高,请输入 Cx ^。 Emacs 会相应地延长当前窗口并使其下方的窗口变小。要使当前窗口更宽,请输入Cx }。 Emacs 使这个窗口变宽,但牺牲了它右边的窗口。
Emacs always splits windows into two equal parts. Such a split is often good enough, but sometimes it's not, particularly if you become a window aficionado. When you have four or five or six windows on your screen at once, controlling each window's size becomes important. Otherwise, the windows you are most interested in will eventually become too small, and useful editing is almost impossible when you can see only five or six lines from a file. If you want to make the window you're working on taller, type C-x ^. Emacs lengthens the current window and makes the one below it smaller, accordingly. To make the current window wider, type C-x }. Emacs makes this window wider, at the expense of the one to the right of it.
要使窗口变小,您可以缩小它们。要垂直缩小窗口,请输入Mxshrink-window。 Emacs 将当前窗口缩小一行,屏幕上的其他窗口相应增大。要水平缩小窗口,请输入 Cx {。此命令使窗口一列变窄,并水平放大屏幕上的其他窗口。
To make windows smaller, you can shrink them. To shrink a window vertically, type M-x shrink-window. Emacs shrinks the current window by one line and the other windows on the screen grow accordingly. To shrink a window horizontally, type C-x {. This command makes the window one column narrower and enlarges the other windows on the screen horizontally.
然而,通常您希望以比一次一行或一列更大的增量进行工作。当您在任何这些命令之前键入Cu时,该命令一次会以四行或四列的增量运行。例如,屏幕上有两个水平窗口,让我们使用Cu Cx ^
来放大james窗口。
Usually you want to work in larger increments than one line or one
column at a time, however. When you type C-u preceding any of these commands, the
command works in increments of four lines or columns at a time. For
example, with two horizontal windows on the screen,
let's use C-u C-x ^
to enlarge the james window.
正如您所期望的,当您增大窗口时,它会自动填充缓冲区中的更多文本。还有调整窗口大小的快捷方式。如果您有一个非常小的缓冲区(例如,包含当天的词汇构建单词及其定义的单行缓冲区),您可以通过键入Cx -(对于收缩窗口-)将窗口缩小到缓冲区的大小如果大于缓冲区)。如果缓冲区大于窗口,则此命令不执行任何操作。键入 Cx +(对于balance-windows)再次创建相同大小的窗口。 (如果您有奇数个窗口,后一个命令也很有用;Cx +在它们之间平均分配显示。)
As you would expect, when you make the window larger, it automatically fills with more text from the buffer. There are shortcuts to sizing windows as well. If you have a very small buffer—for example, a one-line buffer containing the vocabulary-building word for the day and its definition—you can shrink the window to the size of the buffer by typing C-x - (for shrink-window-if-larger-than-buffer). If the buffer is larger than the window, this command does nothing. Typing C-x + (for balance-windows) creates windows of equal size again. (This latter command is also useful if you have an odd number of windows; C-x + divides the display equally among them.)
Emacs 中的 Windows 可以和你的屏幕一样大。然而,窗口的大小是有限制的,这个限制是由变量window-min-height(其默认值是四行)和window-min-width(其默认值是十个字符)指定的。如果您将其他窗口放大到其对应窗口的宽度小于 10 个字符或高度小于 4 行,Emacs 将删除较小的窗口。如果需要,您可以将这些变量设置为其他值;有关设置变量的更多信息请参见第 10 章。
Windows in Emacs can be as big as your screen. There's a limit to how small windows can be, however, and this limit is specified by the variables window-min-height (whose default is four lines) and window-min-width (whose default is ten characters). If you enlarge other windows to the point that their counterparts become less than ten characters wide or four lines high, Emacs deletes the smaller windows. You can set these variables to other values if you want to; more information on setting variables is found in Chapter 10.
特别是如果你正在寻找 对于大文件之间的微小差异,compare-windows命令会派上用场。要使用 Compare-windows,您必须首先在两个窗口中拥有要比较的缓冲区(并排或水平)。转到每个缓冲区的开头,然后输入 Mx Compare-windows。 Emacs 将每个缓冲区滚动到差异所在的位置。它将每个缓冲区中的点放置在差异的位置,因此使用 Cx o在缓冲区之间移动光标将准确显示文件的不同之处。[ 3 ]
Especially if you're looking for minute differences between large files, the compare-windows command comes in handy. To use compare-windows, you must first have the buffers you want to compare in two windows, either side by side or horizontally. Go to the beginning of each buffer, then type M-x compare-windows. Emacs scrolls each buffer to the place where the discrepancy is. It places the point in each buffer at the place of the discrepancy, so using C-x o to move the cursor between buffers will show you exactly where the files differ.[3]
当然,此操作仅发现两个缓冲区之间的第一个差异。找到第二个、第三个等等有点棘手。仅当两个缓冲区中的点完全相同时,compare-windows命令才起作用。因此,您需要先消除两个缓冲区中的差异,然后才能再次键入Mx Compare-windows。 Unix diff命令提供了一种更全面(尽管看起来有些尴尬)的方法来查找两个文件之间的差异。 Emacs 还提供了Ediff的界面,其中包含“比较”菜单(“工具”菜单的子菜单)上的选项。 Ediff 的内容要全面得多;详细信息请参见 第 12 章。
Of course, this maneuver finds only the first difference between the two buffers. Finding the second, third, and so on, is a bit tricky. The compare-windows command works only if the point in both buffers is in exactly the same place. Therefore, you need to move past the discrepancy in both buffers before you can type M-x compare-windows again. The Unix diff command provides a more comprehensive (although somewhat awkward looking) way to find the differences between two files. Emacs also provides an interface to Ediff, with options on the Compare menu (a submenu of the Tools menu). Ediff is far more comprehensive; see Chapter 12 for details.
表 4-4总结了窗口 本章讨论的命令。
Table 4-4 summarizes the window commands discussed in this chapter.
表 4-4。窗口命令
Table 4-4. Window commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
Cx 2 文件 → 分割窗口 C-x 2 File → Split Window |
垂直分割窗口 split-window-vertically |
将当前窗口分成两个窗口,一个在另一个窗口之上。 Divide current window into two windows, one above the other. |
|
CX 3 C-x 3 |
水平分割窗口 split-window-horizontally |
将当前窗口分成两个并排的窗口。 Divide current window into two side-by-side windows. |
|
CX > C-x > |
向右滚动 scroll-right |
向右滚动窗口。 Scroll the window right. |
|
CX < C-x < |
向左滚动 scroll-left |
向左滚动窗口。 Scroll the window left. |
|
CXO C-x o |
其他窗口 other-window |
移至另一个窗口;如果有多个,则移至下一个窗口(请参阅“导航窗口”)。 Move to the other window; if there are several, move to the next window (see "Navigating Windows"). |
|
CX 0 C-x 0 |
删除窗口 delete-window |
删除当前窗口。 Delete the current window. |
|
Cx 1 文件 → 未分割的窗口 C-x 1 File → Unsplit Windows |
删除其他窗口 delete-other-windows |
删除除此窗口之外的所有窗口。 Delete all windows but this one. |
|
(没有任何) (none) |
删除 Windows 上 delete-windows-on |
删除给定缓冲区上的所有窗口。 Delete all windows on a given buffer. |
|
CX^ C-x ^ |
放大窗口 enlarge-window |
让窗户更高。 Make window taller. |
|
(没有任何) (none) |
收缩窗口 shrink-window |
使窗口变短。 Make window shorter. |
|
CX } C-x } |
水平放大窗口 enlarge-window-horizontally |
让窗户更宽。 Make window wider. |
|
CX { C-x { |
水平缩小窗口 shrink-window-horizontally |
让窗口变窄。 Make window narrower. |
|
CX- C-x - |
如果大于缓冲区则缩小窗口 shrink-window-if-larger-than-buffer |
如果缓冲区小于窗口,则缩小窗口。 Make window smaller if buffer is smaller than window. |
|
CX + C-x + |
平衡窗口 balance-windows |
使窗户大小相同。 Make windows the same size. |
|
巨细胞病毒 C-M-v |
滚动其他窗口 scroll-other-window |
滚动其他窗口。 Scroll other window. |
|
CX 4 f C-x 4 f |
查找文件其他窗口 find-file-other-window |
在另一个窗口中查找文件。 Find a file in the other window. |
|
CX 4 b C-x 4 b |
切换到缓冲区其他窗口 switch-to-buffer-other-window |
在另一个窗口中选择一个缓冲区。 Select a buffer in the other window. |
|
(无)工具 → 比较 (Ediff) → 本窗口和下一个窗口 (none)Tools → Compare (Ediff) → This Window and Next Window |
比较窗口 compare-windows |
将此窗口与下一个窗口进行比较并显示第一个差异。 Compare this window with the next window and show the first difference. |
[ 2 ]确实,您无法使用鼠标调整 Emacs 窗口的大小。但是,如果调整 Emacs 框架的大小,它确实会影响窗口的大小,甚至在框架无法显示所有窗口的情况下有时会消除窗口。当然,与往常一样,消除窗口不会影响底层缓冲区。
[2] It's true that you can't resize Emacs windows using the mouse. But if you resize an Emacs frame, it does impact the size of the windows, even eliminating windows at times if the frame cannot display all the windows. Of course, as always, eliminating a window doesn't impact the underlying buffer.
一旦你开始工作 多个文件,记住您在每个文件中的位置变得更加困难。书签提供了一种方便的方式来标记您在文件中的位置,您可以轻松返回到该位置。例如,您可能正在处理具有长路径名的文件。您不必每次启动 Emacs 时都重新输入路径名,只需让 Emacs 查找文件并将光标放在您设置书签的位置即可跳转到您命名为当前项目的书签。
Once you start working with multiple files, remembering just where you were in each one becomes harder. Bookmarks provide a convenient way of marking your place in a file, a place you can easily return to. You might, for example, be working with a file that has a long pathname. Rather than retype the pathname each time you start Emacs, you could just jump to a bookmark you've named current project by having Emacs find the file and put the cursor wherever you set the bookmark.
书签使在任何文件中查找位置的过程变得更加容易。特别是如果您正在处理距主目录几个目录或完全不同的文件系统中的项目,则在文件中添加书签可以轻松返回那里。
Bookmarks make the process of finding your place in any file easier. Particularly if you are working on a project several directories down from your home directory or in a totally different filesystem, putting bookmarks in the file makes it easy to get back there.
当您创建书签时,Emacs 会在您的主目录中创建一个名为.emacs.bmk的书签文件。当您退出 Emacs 时,它会自动将所有新书签保存在此文件中。
When you create a bookmark, Emacs creates a bookmark file in your home directory, called .emacs.bmk. It saves any new bookmarks in this file automatically when you exit Emacs.
书签由用户存储。如果您和其他人访问相同的在线文档集,您可以用您的书签保留您的位置,他们也可以用他们的书签保留他们的位置,永远不会干扰彼此的阅读。
Bookmarks are stored by user. If you and others access the same online documentation set, you can hold your place with your bookmark and they can hold their places with theirs, never interfering with each other's reading.
从“编辑”菜单中,您可以访问“书签”菜单,其中列出了您可能需要的所有书签命令。我们觉得书签的菜单界面特别完善;即使您通常不使用菜单,在这种情况下您也可能需要例外。 (至少在您学习命令之前是这样。书签会让人上瘾,当您经常使用它们时,输入命令比通过菜单访问更容易。)
From the Edit menu, you can access the Bookmarks menu, which lists all the bookmark commands you'll probably ever need. We feel the menu interface for bookmarks is particularly well developed; even if you don't normally use menus, you might want to make an exception in this case. (At least until you learn the commands. Bookmarks are addictive, and when you use them frequently, the commands are easier to type than to reach by menu.)
要将书签放置在
光标位置,键入Cx rm(对于
书签集)。 Emacs 要求提供一个书签名称,该名称实际上可以是任何长度(实际上,只要显示器的宽度即可)并且可以包含空格(socurrent project或Moore
proposal's greatest flaw或
Othello Act 2 Scene 4都可以)。 Emacs 还会在括号中放置一个默认书签,如果您在此会话期间没有使用书签,则会建议文件名(在这种情况下,它会使用书签名称)。按Enter接受默认值,或者键入书签名称,然后按Enter。您现在有了一个书签,可以在任何 Emacs 会话中随时跳转到该书签。
To place a bookmark at the
cursor
position, type C-x r m (for
bookmark-set). Emacs asks for a
bookmark name, which can be virtually any length (practically
speaking, as long as the width of your display) and can include
spaces (so current project or Moore
proposal's greatest flaw or
Othello Act 2 Scene 4 would all be fine). Emacs
also puts a default bookmark in parentheses, suggesting the filename
if you haven't used a bookmark during this session
(in which case it uses the bookmark name). Either press Enter to accept the default or type a bookmark
name and then press Enter. You now
have a bookmark you can jump to at any time, in any Emacs session.
有一个微妙之处:如果您为新书签指定与旧书签相同的名称,Emacs 会假设您只想移动该书签,即使它以前位于另一个文件中。因此,请记住使书签名称具有唯一性,除非您确实想移动它们。
One subtlety: if you give a new bookmark the same name as an old one, Emacs assumes you just want to move the bookmark, even if it was formerly in another file. So remember to make bookmark names unique unless you are really trying to move them.
要移动到书签, 按Cx r b(用于书签跳转)。输入书签的名称,或输入前几个字母并按Tab。 Emacs 要么完成书签的名称,要么为您提供一个可能选择的窗口。 出现书签名称后按Enter键。 Emacs 检索文件并将光标置于书签位置;无论文件的路径多么复杂,都会检索该文件。
To move to a bookmark, press C-x r b (for bookmark-jump). Type the bookmark's name, or type the first few letters and press Tab. Emacs either finishes the bookmark's name or gives you a window of possible choices. Press Enter after the bookmark's name appears. Emacs retrieves the file and places the cursor at the bookmark location; the file is retrieved no matter how complicated its path is.
通过菜单,可以更轻松地移动到书签。当您选择编辑→书签→跳转到书签时,Emacs 将显示可用书签的窗口。选择所需的书签,Emacs 将显示文件,并将光标置于书签位置。如果您设置了许多书签,这非常有用,但我们更喜欢尽可能坚持使用键盘。
With menus, there's an easier way to move to a bookmark. When you select Edit → Bookmarks→ Jump to Bookmark, Emacs displays a window of available bookmarks. Select the bookmark you want, and Emacs displays the file with the cursor in the bookmark's position. This is useful if you have set many bookmarks, but we prefer to stick with the keyboard as much as possible.
你可能会发现
您将书签名称设置得太通用;current
project如果您正在处理项目并且您手中的项目是当前项目,则可能太模糊了。要重命名书签,请输入
Mx bookmark-rename。如果您从键盘进行重命名,Emacs 会提示Old bookmark
name: 并且您输入旧名称并按Enter。 (如果您使用菜单,则可以从窗口中选择旧名称。)然后 Emacs 会询问:New
name,您输入新名称并按Enter,一切都非常简单。重命名书签仅执行此操作,仅此而已:它不会更改书签的位置或其内容;而是会更改书签的位置。它只是改变了它的名字。
You may find that
you
made the name of your bookmark too generic; current
project may be too vague if you are juggling projects and
the one in your hand is the current one. To rename a bookmark, type
M-x bookmark-rename. If you do the
renaming from the keyboard, Emacs prompts Old bookmark
name: and you type the old name and press Enter. (If you use the menus, you select the
old name from a window instead.) Then Emacs asks, New
name: and you type the new name and press Enter, all very straightforwardly. Renaming a
bookmark does just that and nothing else: it doesn't
change the bookmark's location or its contents; it
simply changes its name.
要删除书签, 按 Mx 书签删除。输入要删除的书签的名称或用鼠标选择它。删除书签不会以任何方式影响已标记的文件。
To delete a bookmark, press M-x bookmark-delete. Type the name of the bookmark to delete or select it with the mouse. Deleting a bookmark doesn't in any way affect the file that was marked.
这次讨论提出了一个有趣的问题。如果删除已添加书签的文件中的文本,会发生什么情况?由于书签指向文件中的某个位置而不是一段文本,因此删除文本后书签仍保留在同一位置,就像删除多个段落后光标仍保留在同一位置一样。这个事实比听起来更直观。您不会通过删除标记的文本来删除书签。假设您有一个包含四行的文件。您为第三行添加书签,然后删除第二行到第四行。当您再次跳转到该书签时,它会出现在第一行之后,即文件末尾。
This discussion brings up an interesting question. What happens if you delete text in a file in which you've put a bookmark? Because a bookmark points to a position in a file and not to a piece of text, the bookmark stays in the same place after the text is deleted, just as the cursor remains in the same place after you delete several paragraphs. This fact is more intuitive than it sounds. You don't delete bookmarks by deleting marked text. Let's say you have a file with four lines. You bookmark the third line, then later delete lines two through four. When you jump to that bookmark again, it appears after the first line, the end of the file.
插入文本 以同样的方式工作。书签指向文件中的位置,而不是文本。如果您在第三行之前插入新行,书签将保留在文件中您设置它的位置,在本例中为新行的开头。如果您移动文本,书签将指向文件中的同一位置,即您设置文本的行和列。
Inserting text works the same way. Bookmarks point to a position in a file, not to text. If you insert a new line before the third line, the bookmark remains at the point in the file where you set it, in this case, the beginning of the new line. If you move text around, the bookmark points to the same location in the file, the line and column where you set it.
如果删除其中包含书签的文件会发生什么?如果您删除整个文件,甚至重命名它,然后尝试访问附加到该文件的书签,Emacs 会给出以下错误消息:
What happens if you delete a file that has a bookmark in it? If you delete the whole file or even rename it and then try to access a bookmark attached to the file, Emacs gives you the following error message:
如果按y,您可以为该文件提供一个新路径,如果您确实只是重命名或移动该文件但没有删除它,则该路径效果很好。但是,如果您按 n,Emacs 会向您显示一条消息以及一些建议:
If you press y, you can give a new path to the file, which works well if you really just renamed or moved the file but didn't delete it. If you press n, however, Emacs gives you a message, along with some advice:
书签未重新定位,请考虑将其删除
Bookmark not relocated, consider removing it
换句话说,Emacs 认为没有人需要为不存在的文件添加书签,我们也倾向于同意。
In other words, Emacs argues that no one needs bookmarks to nonexistent files, and we're inclined to agree.
记住缓冲区列表 我们在本章前面讨论过?书签有一个类似的列表,其中包含一个字母命令,使您可以一次使用所有书签。
Remember the buffer list we discussed earlier in this chapter? Bookmarks have a similar list with one-letter commands that allow you to work with all your bookmarks at once.
要使用书签列表,请键入Cx r l(小写字母“L”)。缓冲区*Bookmark
List*出现。
To work with a list of bookmarks, type C-x r
l (the lowercase letter
"L"). The *Bookmark
List* buffer appears.
|
类型:Cx rl Type: C-x r l |
|
|
|
Emacs 显示书签列表以及关联文件的路径。 Emacs displays a list of bookmarks and the path to the associated files. |
如果按Enter、f或j,Emacs 将显示已添加书签的文件,并且光标位于已添加书签的位置。在书签列表中,按d标记要删除的书签,然后 按 x删除它们(与缓冲区列表不同,在书签列表中,删除是您需要x命令的唯一原因)。如果您改变主意,请在按x之前按Del删除 d。按r 重命名书签,Emacs 会提示您输入新名称。要保存所有书签,请按s。您可以标记多个书签,然后通过在书签旁边键入m显示其关联的文件。您标记的书签旁边会出现 >。当你标记完所有你想要的内容后,输入v(代表view),Emacs 就会调出与书签相关的文件,并在多个窗口中显示它们(当然,光标位于标记的位置)。如果您只想移至一个已添加书签的文件,则可以按v键而不先标记书签。
If you press Enter, f, or j, Emacs displays the bookmarked file with the cursor in the bookmarked location. From the bookmark list, press d to mark bookmarks for deletion, then x to delete them (unlike in the buffer list, in the bookmark list, deleting is the only reason you need the x command). If you change your mind, press Del to remove the d before you press x. Pressing r renames a bookmark, and Emacs prompts you for the new name. To save all the bookmarks, press s. You can mark several bookmarks and then display their associated files by typing m next to the bookmarks. A > appears beside bookmarks you've marked. When you've marked all you want, type v (for view) and Emacs pulls up the files associated with the bookmarks and displays them in multiple windows (with the cursor at the bookmarked location, of course). If you just want to move to one bookmarked file, you can press v without marking the bookmark first.
您可以更改书签列表的显示 稍微按t。默认情况下,该列表显示书签的名称,后跟与其关联的文件的完整路径。如果按t(用于切换),则仅显示书签名称。
You can change the display of the bookmark list slightly by pressing t. By default, the list shows a bookmark's name, followed by the complete path to the file with which it is associated. If you press t (for toggle), only the bookmark names appear.
表 4-5总结了书签列表 命令。它包括一些与注释相关的命令;我们将在下一节中介绍这些内容。
Table 4-5 summarizes the bookmark list commands. It includes a few commands relating to annotations; we'll cover these in the next section.
表 4-5。编辑书签列表的命令
Table 4-5. Commands for editing the bookmark list
|
命令 Command |
行动 Action |
|---|---|
|
输入、 f或j Enter, f, or j |
转到当前行的书签。 Go to the bookmark on the current line. |
|
钴或 氧 C-o or o |
在另一个窗口中打开当前行的书签;o将光标移动到该窗口;Co将光标保留在当前窗口中。 Open the bookmark on the current line in another window; o moves the cursor to that window; C-o keeps the cursor in the current window. |
|
d、 Cd或 k d, C-d, or k |
将书签标记为删除。 Flag bookmark for deletion. |
|
r r |
重命名书签。 Rename bookmark. |
|
s s |
保存列出的所有书签。 Save all bookmarks listed. |
|
米 m |
标记要在多个窗口中显示的书签。 Mark bookmarks to be displayed in multiple windows. |
|
v v |
显示已标记的书签,如果没有标记,则显示光标所在的书签。 Display marked bookmarks or the one the cursor is on if none are marked. |
|
t t |
切换与书签关联的文件路径的显示。 Toggle display of paths to files associated with bookmarks. |
|
w w |
在迷你缓冲区中,显示与书签关联的文件的位置。 In the minibuffer, display location of file associated with bookmark. |
|
X x |
删除标记为删除的书签。 Delete bookmarks flagged for deletion. |
|
你 u |
从书签中删除标记。 Remove mark from bookmark. |
|
德尔 Del |
从上一行的书签中删除标记或移至上一行(如果没有标记)。 Remove mark from bookmark on previous line or move to the previous line (if there is no mark). |
|
q q |
退出书签列表。 Exit bookmark list. |
|
空格或 n Space or n |
向下移动一行。 Move down a line. |
|
p p |
向上移动一行。 Move up a line. |
|
我 l |
加载书签文件(默认文件除外)。 Load a bookmark file (other than the default). |
|
A A |
显示所有注释。 Display all annotations. |
|
A a |
显示当前书签的注释。 Display annotation for current bookmark. |
|
e e |
编辑(或创建)当前书签的注释。 Edit (or create) annotation for the current bookmark. |
您可以添加注释 到您的书签。这些注释可以提供您想要的任何类型的信息:有关相关文件的详细信息、您正在使用它做什么、项目中其他人在查看您的文件时要查看的文档,或者您真正想要的任何信息。
You can add annotations to your bookmarks. These annotations can provide any type of information you want: details about the file in question, what you are doing with it, documentation for someone else on your project to review when looking at your files, or really anything you want.
最容易从书签列表本身添加注释。使用Cx rl打开书签列表,然后移至要注释的书签行。键入 e,用于编辑注释的命令。
Annotations are most easily added from the bookmark list itself. Open the bookmark list using C-x r l, then move to the line of the bookmark you want to annotate. Type e, the command to edit an annotation.
|
从书签列表中,输入:e From the bookmark list, type: e |
|
|
|
Emacs 打开一个 Emacs opens a |
Emacs 在此缓冲区中提供了一些有关操作的指导。它表示所有以 a 开头的行 注释标记 (#) 将被删除,并按抄送抄送保存并退出注释缓冲区。
Emacs provides some guidance in this buffer about what to do. It says that all lines that start with a comment mark (#) will be deleted and that you press C-c C-c to save and exit the annotations buffer.
注释包含被注释掉的行,不会成为注释的一部分,但如果您想保留作者和日期行(注释的逻辑部分),只需通过删除开头的 # 来取消注释这些行。然后,您可以添加所需的任何注释,然后按抄送抄送退出窗口。
The annotation includes lines that are commented out and won't become part of the annotation, but if you'd like to keep the Author and Date lines (logical portions of an annotation), just uncomment those lines by deleting the initial #. You then add any annotation you would like and press C-c C-c to exit the window.
注释表现出一些行为,即使不是错误,至少也是令人烦恼的。首先,Emacs 定义了 # 作为默认的填充前缀。您必须更改它(有关详细信息,请参阅第 6 章)或删除初始 #(如果 Emacs 插入了它)。其次,更重要的是,当您退出 Emacs 时,Emacs 不会自动保存注释。如果您设置书签,Emacs 会自动保存书签文件(实际上无需询问)。如果您设置注释但在会话期间未添加或移动书签,则必须通过键入 Mx bookmark-save手动保存书签文件。
Annotations exhibit a couple of behaviors that are at least annoying if not bugs. First, Emacs defines a # as the default fill prefix. You must either change that (see Chapter 6 for details) or delete the initial # if Emacs inserts it. Second, and more critically, Emacs doesn't automatically save annotations when you exit Emacs. If you set a bookmark, Emacs saves the bookmarks file automatically (and in fact without asking). If you set an annotation but do not add or move a bookmark during the session, you must save the bookmarks file manually by typing M-x bookmark-save.
添加注释后,Emacs 会在书签名称前添加一个星号 (*),作为书签已被注释的视觉指示。要显示当前书签的注释,请按 a。要显示所有注释,请按 A。
After you add an annotation, Emacs puts an asterisk (*) before the bookmark name as a visual indication that the bookmark has been annotated. To display an annotation for the current bookmark, press a. To display all annotations, press A.
当您跳转到书签或从书签列表移至已添加书签的文件时,注释会自动显示在另一个窗口中(但不要在此窗口中编辑它们;您必须使用前面描述的过程)。如果您以其他方式打开加书签的文件(例如使用Cx Cf ),则不会显示注释。
When you jump to a bookmark or move to a bookmarked file from the bookmark list, annotations are automatically displayed in another window (but don't edit them in this window; you must use the procedure described earlier). If you open the bookmarked file some other way (using C-x C-f, for example), annotations are not displayed.
除了那些我们已经 讨论过之后,还有一些更深奥的书签命令。其中包括 bookmark-insert,它将添加书签的文件的文本插入到光标位置;bookmark-write,提示输入新文件名来保存书签;和bookmark-load,加载这些单独的书签文件。这些命令不如其他命令有用,但您可能会想到一些我们没有想到的巧妙用途。
In addition to those we've discussed, there are a few more esoteric bookmark commands. These include bookmark-insert, which inserts the text of the bookmarked file at the cursor position; bookmark-write, which prompts for a new filename in which to save bookmarks; and bookmark-load, to load these separate bookmark files. These commands are less useful than the others, but you may think of some clever uses we have not.
表 4-6总结了书签命令。
Table 4-6 summarizes bookmark commands.
表 4-6。书签命令
Table 4-6. Bookmark commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
Cx rm 编辑 → 书签 → 设置书签 C-x r m Edit → Bookmarks → Set Bookmark |
书签集 bookmark-set |
在当前光标位置设置书签。 Set a bookmark at the current cursor position. |
|
Cx rb 编辑 → 书签 → 跳转到书签 C-x r b Edit → Bookmarks → Jump to Bookmark |
书签跳转 bookmark-jump |
跳转到书签。 Jump to a bookmark. |
|
(无)编辑 → 书签 → 重命名书签 (none)Edit → Bookmarks → Rename Bookmark |
书签重命名 bookmark-rename |
重命名书签。 Rename a bookmark. |
|
(无)编辑 → 书签 → 删除书签 (none)Edit → Bookmarks → Delete Bookmark |
书签删除 bookmark-delete |
删除书签。 Delete a bookmark. |
|
(无)编辑 → 书签 → 保存书签 (none)Edit → Bookmarks → Save Bookmarks |
书签保存 bookmark-save |
将所有书签保存在默认文件中。 Save all bookmarks in default file. |
|
Cx rl 编辑 → 书签 → 编辑书签列表 C-x r l Edit → Bookmarks → Edit Bookmark List |
书签菜单列表 bookmark-menu-list |
移至 Move to |
|
(无)编辑 → 书签 → 插入内容 (none)Edit → Bookmarks → Insert Contents |
书签插入 bookmark-insert |
插入与给定书签关联的文件的全文。 Insert full text of file associated with a given bookmark. |
|
(无)编辑 → 书签 → 将书签另存为 (none)Edit → Bookmarks → Save Bookmarks As |
书签写入 bookmark-write |
将所有书签保存在指定文件中。 Save all bookmarks in a specified file. |
|
(无)编辑 → 书签 → 加载书签文件 (none)Edit → Bookmarks → Load a Bookmark File |
书签加载 bookmark-load |
从指定文件加载书签。 Load bookmarks from specified file. |
|
(无)编辑 → 书签 → 插入位置 (none)Edit → Bookmarks → Insert Location |
书签插入位置 bookmark-insert-location |
在光标位置插入给定书签的路径。 Insert the path to a given bookmark at the cursor position. |
既然您已经知道如何使用多个缓冲区、帧和窗口,为什么不阅读下一章来发现可以用它们做的一些事情呢?本章中已经提到了一些内容,例如使用目录编辑器和在 Emacs 中使用命令行。
Now that you know how to work with multiple buffers, frames, and windows, why not read the next chapter to discover some of the things you can do with them? Some, like using the directory editor and working with the command line from within Emacs, have been alluded to in this chapter.
您通过命令提示符执行的许多日常操作都可以在 Emacs 中完成。您可以执行命令、使用目录和打印文件——所有这些都无需离开 Emacs。更改任务就像在缓冲区之间跳转一样简单。
Many of the everyday things you do from a command prompt can be done from within Emacs. You can execute commands, work with directories, and print files—all without leaving Emacs. Changing tasks is as simple as jumping between buffers.
这有什么重要的呢?当然,能够轻松地在任务之间移动是件好事。更重要的是,无论您在做什么,您都拥有相同的编辑环境:您可以使用所有 Emacs 编辑命令来处理文件,给出 shell 命令,然后启动目录编辑器 Dired 来执行操作一些文件维护。将文本从一个窗口移动到另一个窗口很简单。您可以执行命令,然后使用 Emacs 命令将结果剪切并粘贴到文件中。如果您尝试编译程序并不断收到错误消息,则可以将交互式会话保存为文件并与某人讨论该问题。尽管现代窗口系统有许多优点,Emacs 通常提供了集成您日常所做的多种工作的最佳方式。
What's important about this? Of course, it's nice to be able to move between tasks easily. What's even more important is that you have the same editing environment no matter what you're doing: you can use all of the Emacs editing commands to work on a file, give shell commands, then start up Dired, the directory editor, to do some file maintenance. It is simple to move text from one window to another. You can execute a command and then use Emacs commands to cut and paste the results into a file. If you're trying to compile a program and keep getting error messages, you can save the interactive session as a file and confer with someone about the problem. Despite the many advantages of modern window systems, Emacs often provides the best way to integrate the many kinds of work you do daily.
本章中的大部分信息涉及 Emacs 和操作系统之间的集成。 Emacs 是最常见的 Unix 编辑器,因此请原谅我们在这方面的偏见。但我们很高兴地报告,对于其他平台上的 GNU Emacs 用户,仍然可以与操作系统集成;您可以使用 shell 模式运行命令,并可以使用 Dired 编辑目录。无论您的平台是什么,都没有理由离开 Emacs。
Much of the information in this chapter involves integration between Emacs and the operating system. Emacs is most commonly a Unix editor, so forgive us for a bias in that direction. But we are happy to report that for users of GNU Emacs on other platforms, integration with the operating system is still available; you can use shell mode to run commands and can edit directories with Dired. There's no reason to leave Emacs no matter what your platform is.
最重要的功能之一 Emacs 的特色在于它能够在缓冲区中运行命令 shell。一旦启动了 shell 缓冲区,您就可以在 Emacs 中完成所有正常的命令行工作。这给你买了什么?
One of the most important features of Emacs is its ability to run a command shell in a buffer. Once you have started a shell buffer, you can do all of your normal command-line work within Emacs. What does this buy you?
您不必离开 Emacs 即可获得命令提示符。如果您想打印或编译正在编辑的文件,您可以立即执行。
You don't have to leave Emacs to get a command prompt. If you want to print or compile a file that you're editing, you can do it immediately.
您可以使用 Emacs 编辑功能来编写命令。
You can use Emacs editing features to write your commands.
您可以使用 Emacs 编辑功能来“备份”命令列表、复制旧命令、修改它并再次执行。
You can use Emacs editing features to "back up" through your command list, copy an old command, modify it, and execute it again.
您可以保存 shell 缓冲区,保留编辑会话的记录,其中自动包含您运行的每个命令的输出。对于调试或记住不经常运行的命令,这可能是无价的。
You can save your shell buffer, keeping a transcript of your editing session—which automatically includes the output from every command that you ran. For debugging or remembering commands you run infrequently, this can be invaluable.
您可以将命令的输出复制到文件或另一个命令中。
You can copy output from commands into a file or into another command.
您可以将复杂的命令保存在文件中并在提示符下插入该文件,而不是重新键入命令。
You can save complex commands in a file and insert the file at the prompt, rather than retyping the command.
当您习惯在 Emacs 中工作时,您无疑会发现越来越多的使用 shell 模式的方法。
As you get used to working within Emacs, you will undoubtedly discover more and more ways to put shell mode to use.
在本节中,我们讨论 shell 模式。在本章后面,我们将讨论在 Emacs 中进行简单时间管理的目录编辑、打印以及日历和日记功能。现在,我们将从 shell 模式的一个简单变体开始,该功能允许您一次执行一个命令。
In this section, we discuss shell mode. Later in this chapter, we discuss directory editing, printing, and calendar and diary features for doing simple time management in Emacs. Right now, we'll start with a simple variation on shell mode, a feature that lets you execute commands one at a time.
运行命令时
如果您正处于 Emacs 会话中,请输入M-!。 Emacs 询问您要运行的命令。键入命令并按
Enter。然后,Emacs 打开一个名为 的窗口*Shell Command Output*,在其中显示命令的结果。
To run a command while
you're
in an Emacs session, type M-!. Emacs
asks for the command you want to run. Type the command and press
Enter. Emacs then opens a window
called *Shell Command Output* where it displays
the results of your command.
|
类型:diff Joyce Joyce2 Type: diff joyce joyce2 |
|
|
|
Emacs 执行diff命令并将输出放入 Emacs executes the diff command and
puts the output into a |
由于diff命令的输出 位于缓冲区中,因此您可以对其进行编辑、保存或执行任何其他操作。当然,如果操作系统没有 diff命令或者由于某种原因无法访问,则该命令失败。
Because the output from the diff command is in a buffer, you can edit it, save it, or do anything else you would like with it. Of course, if the operating system has no diff command or cannot access it for some reason, this command fails.
shell 命令工具的一个有趣的变化是您可以使用缓冲区的一个区域而不是传统的文件作为命令的输入。例如,假设我们要对电话列表进行排序。首先,我们将光标放在列表中的某个位置(例如,在 的第一个字符上Liam),然后给出
标记段落命令 ( Mh )。该命令将电话列表定义为一个区域,光标位于段落开头,标记位于段落末尾。
An interesting twist to the shell command facility is that you can
use a region of a buffer rather than a traditional file as input to
the command. For example, let's say we want to sort
a phone list. First, we put the cursor somewhere in the list (say, on
the first character of Liam), then we give the
mark-paragraph command (M-h). This command defines the phone list as a
region, with the cursor at the beginning of the paragraph and the
mark at the end.
在下面的示例中,阴影区域显示了我们要排序的区域的范围。选择区域后,我们按M-|(对于shell-command-on-region); Emacs 提示运行 shell 命令。
In the following example, the shaded area shows the extent of the region we want to sort. After selecting a region, we press M-| (for shell-command-on-region); Emacs prompts for the shell command to run.
|
类型:Mh M-| Type: M-h M-| |
|
|
|
Emacs 提示您输入要执行的命令 (Windows)。 Emacs prompts you for a command to execute (Windows). |
现在我们给出命令sort而不指定任何输入文件。 Emacs 正在为我们处理输入。
Now we give the command sort without specifying any input file. Emacs is taking care of the input for us.
Emacs 已对电话列表(即该区域内的所有内容)进行了排序。
Emacs has sorted the phone list (i.e., everything within the region).
M-!的一个有用的变体把输出
直接进入当前缓冲区,而不是进入一个*Shell Command Output*
缓冲区。为此,请在命令前加上Cu:例如Cu M-!运行 shell 命令并将输出放入当前缓冲区中。
A useful variation for M-! puts the
output
directly into the current
buffer, rather than into a *Shell Command Output*
buffer. To do so, precede the command with C-u: for example, C-u
M-! runs a shell command and puts the output in the
current buffer.
现在我们准备好了
讨论 shell 模式,即运行命令的交互式工具。要启动 shell 缓冲区,请输入Mx shell Enter。这将创建一个名为 的缓冲区
*shell*。您会在此缓冲区中看到 shell 的提示。 (这默认为您常用的 shell;您可以替换另一个 shell 以在 Emacs 中使用。请参阅本章后面的“哪个 shell?”。)
Now we're ready
to
discuss shell mode, the interactive facility for running commands. To
start a shell buffer, type M-x shell
Enter. This creates a buffer named
*shell*. You see the prompt for your shell within
this buffer. (This defaults to your usual shell; you can substitute
another shell to use in Emacs. See "Which
shell?" later in this chapter.)
图 5-1。适用于 Linux、Mac OS X 和 Windows 的 Shell 缓冲区
Figure 5-1. Shell buffers for Linux, Mac OS X, and Windows
在大多数情况下,shell 模式与普通命令界面完全相同,只是您可以使用 Emacs 在键入命令时对其进行编辑。您可以将命令从一个位置复制到另一个位置、将结果复制到文件中、将整个 shell 缓冲区保存到文件中,等等。请注意,在图 5-1中,Emacs 在菜单栏中添加了一些项目(Complete、In/Out 和 Signals)。
For the most part, shell mode is exactly like the normal command interface, except that you can use Emacs to edit the commands as you type them. You can copy commands from one place to another, copy the results into a file, save the whole shell buffer to a file, and so on. Note in Figure 5-1 that Emacs has added a few items to the menu bar (Complete, In/Out, and Signals).
不过,有一些技巧值得了解。例如,您通常通过键入Cc来中断命令。如果您在 shell 模式下键入Cc,Emacs 会认为Cc是为其指定的命令的一部分,因为许多 Emacs 命令以 Cc开头。因此,您必须键入 Cc Cc来终止当前作业。同样,在 Unix 下,您可以键入Cc Cz (而不是Cz )来停止作业,并键入 Cc Cd (而不是Cd ),等等。 (抄送 Cd并不是绝对必要的,因为 Emacs 在上下文中理解Cd。如果您位于缓冲区末尾,Cd表示“文件结尾”;如果您位于其他位置,它会删除一个字符。)或者,您可以如果需要,从“信号”菜单中选择选项而不是使用控制字符(例如,选择EOF而不是键入Cd)。
A few tricks are worth knowing, though. For example, you normally interrupt a command by typing C-c. If you type C-c in shell mode, Emacs thinks that the C-c is part of a command meant for it, because many Emacs commands start with C-c. Therefore, you have to type C-c C-c to terminate the current job. Likewise, under Unix, you type C-c C-z to stop a job, instead of C-z, and C-c C-d instead of C-d, and so on. (C-c C-d is not strictly necessary because Emacs understands C-d in context. If you're at the end of the buffer, C-d means "end of file"; if you're anywhere else, it deletes a character.) Alternatively, you can select options from the Signals menu rather than using control characters, if desired (for example, selecting EOF instead of typing C-d).
Shell 模式还提供了一些方便的快捷方式。命令 Mp检索您输入的最后一个 shell 命令,无论它位于缓冲区的后面多远。连续键入Mp将返回较早的命令。
Shell mode also provides a few convenient shortcuts. The command M-p retrieves the last shell command you typed, no matter how far back in the buffer it is. Typing successive M-p's brings back earlier commands.
|
类型:MP Type: M-p |
|
|
|
Mp检索最后一个命令,即使它不在屏幕上 (Mac OS X)。 M-p retrieves the last command, even if it isn't on the screen (Mac OS X). |
在此示例中,前面的命令是more dickensxmas.tex。它不再出现在屏幕上;它的输出已经把它推下了顶峰。Mp(用于comint-previous-input)检索命令,但不执行它;您可以在按Enter之前编辑命令。要查找后续命令,请键入Mn。
In this example, the previous command was more dickensxmas.tex. It's no longer on the screen; its output has pushed it off the top. M-p (for comint-previous-input) retrieves the command, but doesn't execute it; you can edit the command before pressing Enter. To find subsequent commands, type M-n.
如果这些命令响起 你应该很熟悉。它们是历史命令,与我们在第 3 章中讨论的迷你缓冲区历史命令相同。输入 /输出菜单专门用于处理命令历史记录。
If these commands sound familiar to you, they should. They are history commands, which are identical to the minibuffer history commands we discussed in Chapter 3. The In/Out menu is devoted to working with command history.
Enter和Tab在 shell 模式下有特殊功能。按Enter会执行光标所在行的命令,即使您将光标向上移动到要再次执行的先前命令的行也是如此。当您按Enter时,Emacs 会将命令复制到缓冲区的末尾并执行它。当然,您可以在按Enter之前修改命令。
Enter and Tab have special functions in shell mode. Pressing Enter executes the command on the line where the cursor is, even if you move the cursor up to the line of an earlier command you want to execute again. When you press Enter, Emacs copies the command to the end of the buffer and executes it. Of course, you can modify the command before pressing Enter.
按 T ab 键可启用 Emacs 补全功能;对操作系统命令、文件名和变量使用补全。请注意,系统命令的完成在 Linux 和 Mac OS X 等 Unix 实现上效果最好;例如,Emacs 似乎无法找到所有可能的 Windows 命令。
Pressing Tab puts the Emacs completion feature into action; use completion for operating system commands, filenames, and variables. Note that the completion of system commands works best on Unix implementations like Linux and Mac OS X; Emacs doesn't seem to find all the possible Windows commands, for example.
如果您键入的命令会产生大量输出,从而使您的会话变得混乱,那么有一种简单的方法可以摆脱它。输入Cc Co(用于comint-kill-output)。
If you type a command that produces a lot of output, cluttering up your session, there's an easy way to get rid of it. Type C-c C-o (for comint-kill-output).
|
类型:CC Co Type: C-c C-o |
|
|
|
Cc Co自动删除最后一个命令的输出 (Mac OS X)。 C-c C-o automatically deletes the output from the last command (Mac OS X). |
上一个命令 ( ls-la ) 保留在屏幕上,但其输出(一长串文件)被删除。 Cc Co只能删除最近命令的输出;它无法删除以前命令的输出。
The previous command (ls-la) remains on the screen, but its output, a long list of files, is deleted. C-c C-o can delete output from only the most recent command; it can't delete output from your previous commands.
shell 模式的另一个有用命令是Cc Cr(用于comint-show-output)。如果命令产生大量输出并导致前几行输出滚出屏幕,则此命令非常有用。Cc Cr重新定位窗口,以便上一个命令的第一行输出位于窗口的顶部。如果您想查看输出的结尾,请输入Cc Ce(对于comint-show-maximum-output);该命令将输入的最后一行移动到窗口的底部。
Another useful command for shell mode is C-c C-r (for comint-show-output). This command is useful if a command produces a lot of output and causes the first few lines of output to scroll off the screen. C-c C-r repositions the window so the first line of output from your last command is at the top of the window. If you want to see the end of the output instead, type C-c C-e (for comint-show-maximum-output); this command moves the last line of the input to the bottom of the window.
当你写一本书时,按段落移动是有意义的,但是当你使用 shell 时,移动 按输出组更有帮助。输出组 由命令及其输出组成。要移动到上一个输出组,请键入Cc Cp。要移动到下一个输出组,请键入Cc Cn。
When you're writing a book, moving by paragraphs makes sense, but when you're using a shell, moving by output group is more helpful. An output group consists of a command and its output. To move to the previous output group, type C-c C-p. To move to the next output group, type C-c C-n.
shell 模式的优点是您可以启动命令,然后在命令运行时编辑另一个缓冲区。 shell 缓冲区不需要在屏幕上;只需输入Mx shell即可再次恢复缓冲区。
An advantage of shell mode is that you can start a command and then edit another buffer while the command runs. The shell buffer doesn't need to be onscreen; just type M-x shell to get the buffer back again.
您可以运行多个 shell 缓冲区立刻;只需使用命令Mx rename-uniquely重命名您的 shell 缓冲区。您可以启动另一个 shell 缓冲区,然后再启动一个、再启动一个,只要您需要处理所有任务即可。
You can have multiple shell buffers running at once; just use the command M-x rename-uniquely to rename your shell buffer. You can start another shell buffer, and another, and another—as many as you need to juggle all your tasks.
通常,Emacs 在 shell 模式下使用默认 shell。在 Windows 下,这是cmd.exe(熟悉的 C:\>提示符或近亲)。[ 1 ]但是 Unix 有多种可用的 shell,包括 GNU 项目的bash和 zed shell zsh。无论您通常使用什么 shell,当您进入 shell 模式时,Emacs 都会启动它。
Normally, Emacs uses your default shell in shell mode. Under Windows that's cmd.exe (the familiar C:\> prompt or a close relative).[1] But Unix has a wide variety of available shells, including the GNU Project's bash and the zed shell, zsh. Whatever shell you normally use, that's what Emacs starts when you enter shell mode.
Emacs 如何知道启动哪个 shell?首先,它查看变量shell-file-name。然后它查找名为ESHELL的 Unix 环境变量。最后它查找名为SHELL的环境变量。如果您想在 Emacs 中运行另一个特定的 shell(例如 zed shell),您可以将以下命令添加到您的.emacs文件中:
How does Emacs know which shell to start? First, it looks at the variable shell-file-name. Then it looks for a Unix environment variable named ESHELL. Finally it looks for an environment variable named SHELL. If you want to run another particular shell (for example, the zed shell) when you're in Emacs, you can add the following command to your .emacs file:
(setq shell-文件名“/bin/zsh”)
(setq shell-file-name "/bin/zsh")
当 Emacs 启动交互式 shell 时,它会在 shell 的正常启动文件之后运行一个附加的初始化文件。该文件的名称是 .emacs_shell-name,其中 shell-name是您要在 Emacs 中使用的 shell 的名称。它必须位于您的主目录中。例如,如果您使用 C shell,则可以通过将仅 Emacs 的启动命令放置在文件.emacs_csh中来添加它们。假设当您在 Emacs 中时,您想要将提示符更改为emacs:%并且希望将名为WITHIN_EDITOR的环境变量设置为 T。这是.emacs_csh文件的内容:
When Emacs starts an interactive shell, it runs an additional initialization file after your shell's normal startup files. The name of this file is .emacs_shell-name, where shell-name is the name of the shell you want to use in Emacs. It must be located in your home directory. For example, if you use the C shell, you can add Emacs-only startup commands by placing them in the file .emacs_csh. Let's say that when you're in Emacs, you want to change the prompt to emacs:% and you want an environment variable called WITHIN_EDITOR to be set to T. Here's the contents of your .emacs_csh file:
设置提示=“emacs:%” setenvWITHIN_EDITOR T
set prompt="emacs:% " setenv WITHIN_EDITOR T
在 shell 缓冲区内,Emacs 还将环境变量 EMACS设置为t,并将终端类型(TERM变量)设置为emacs。
Within a shell buffer, Emacs also sets the environment variable EMACS to t, and sets your terminal type (the TERM variable) to emacs.
默认情况下,shell 模式会显示您键入的所有内容,其中包括密码 — 如果有人在您身后窥视,情况就不是一个好情况。然而,有一种方法可以解决这个问题。在键入密码之前,请键入Mx send-invisible。 Emacs 要求提供未回显的文本。当您键入一个字符时,Emacs 会在迷你缓冲区中放入一个星号。按 Enter 键,Emacs 输入密码而不显示它。要让 Emacs 在您键入密码时隐藏密码,请将以下两行添加到您的.emacs文件中:
By default, shell mode displays everything you type and that includes passwords—not a good situation if someone is peering over your shoulder. There is a way around this problem, however. Before you type the password, type M-x send-invisible. Emacs asks for the nonechoed text. When you type a character, Emacs puts an asterisk in the minibuffer. Press Enter and Emacs enters the password without displaying it. To have Emacs hide passwords as you type them, add the following two lines to your .emacs file:
(添加钩子'comint-output-filter-functions 'comint-watch-password-prompt)
(add-hook 'comint-output-filter-functions 'comint-watch-for-password-prompt)
每当屏幕上出现密码提示时,Emacs 都会在迷你缓冲区中请求未回显的文本,以确保密码永远不会显示。表 5-1总结了 shell 模式命令。
Emacs asks for nonechoed text in the minibuffer whenever a password prompt appears on the screen, making sure that the password is never displayed. Table 5-1 summarizes shell mode commands.
表 5-1。 Shell 模式命令
Table 5-1. Shell mode commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
(没有任何) (none) |
壳 shell |
进入外壳模式。 Enter shell mode. |
|
抄送抄送 信号 → BREAK C-c C-c Signals → BREAK |
comint 中断子作业 comint-interrupt-subjob |
中断当前工作;相当于抄送。 Interrupt current job; equivalent to C-c. |
|
光盘 C-d |
comint-delchar-或-也许-eof comint-delchar-or-maybe-eof |
如果位于缓冲区末尾,则发送 EOF 字符;删除其他地方的字符。 Send EOF character if at end of buffer; delete a character elsewhere. |
|
抄送镉 信号 → EOF C-c C-d Signals → EOF |
comint-发送-eof comint-send-eof |
发送 EOF 字符。 Send EOF character. |
|
铜铜 C-c C-u |
comint-kill-输入 comint-kill-input |
擦除当前行;相当于Unix shell 中的Cu 。 Erase current line; equivalent to C-u in Unix shells. |
|
抄送 Cz 信号 → 停止 C-c C-z Signals → STOP |
comint-停止-子作业 comint-stop-subjob |
暂停或停止工作;Unix shell 中的Cz 。 Suspend or stop a job; C-z in Unix shells. |
|
Mp 输入/输出 → 上一个输入 M-p In/Out → Previous Input |
comint-前一个输入 comint-previous-input |
检索以前的命令(可以重复查找以前的命令)。 Retrieve previous commands (can be repeated to find earlier commands). |
|
Mn 输入/输出 → 下一个输入 M-n In/Out → Next Input |
comint 下一个输入 comint-next-input |
检索后续命令(可以重复以查找更多最近的命令)。 Retrieve subsequent commands (can be repeated to find more recent commands). |
|
进入 Enter |
comint-发送-输入 comint-send-input |
在当前行发送输入。 Send input on current line. |
|
标签 Tab |
comint 动态完成 comint-dynamic-complete |
完成当前命令、文件名或变量名。 Complete current command, filename, or variable name. |
|
Cc Co In/Out → 删除当前输出组 C-c C-o In/Out → Delete Current Output Group |
comint-kill-输出 comint-kill-output |
删除最后一个命令的输出。 Delete output from last command. |
|
CC铬 C-c C-r |
comint 显示输出 comint-show-output |
将输出的第一行移动到窗口顶部。 Move first line of output to top of window. |
|
Cc Ce In/Out → 显示最大输出 C-c C-e In/Out → Show Maximum Output |
comint 显示最大输出 comint-show-maximum-output |
将输出的最后一行移动到窗口底部。 Move last line of output to bottom of window. |
|
Cc Cp In/Out → 向后输出组 C-c C-p In/Out → Backward Output Group |
comint-上一个提示符 comint-previous-prompt |
移至上一个命令。 Move to previous command. |
|
Cc Cn In/Out → 正向输出组 C-c C-n In/Out → Forward Output Group |
comint 下一个提示符 comint-next-prompt |
移至下一个命令。 Move to next command. |
[ 1 ]感谢 Cygwin ( http://cygwin.com/ ),您在 Windows 下也有选择。例如,如果您想运行 Cygwin 的 bash,您可以在 Ngai Kim Hoong 的该主题页面上找到有关如何设置的有用信息:http://www.khngai.com/emacs/cygwin.php。
[1] You do have choices under Windows as well, thanks to Cygwin (http://cygwin.com/). For example, if you wanted to run Cygwin's bash, you'll find helpful information on how to set that up on Ngai Kim Hoong's page on that topic at http://www.khngai.com/emacs/cygwin.php.
Dired 是最有趣的之一 Emacs 的功能。使用 Dired,您可以查看目录中所有文件的列表,删除它们,重命名它们,复制它们,并执行几乎所有基本文件操作。更重要的是,Dired 可以提高您的工作效率。例如,您可以处理文件组,删除、移动、压缩甚至查询替换其中的字符串。
Dired is one of the most interesting features of Emacs. With Dired, you can look at a listing of all the files in a directory, delete them, rename them, copy them, and perform almost all basic file operations. More important, Dired can make you more productive. For example, you can work with groups of files, deleting, moving, compressing, or even query-replacing strings in them.
有多种方法可以开始目录编辑。如果您不在 Emacs 中,请使用目录名称作为参数来调用 Emacs,例如:
There are several ways to start directory editing. If you're not in Emacs, invoke Emacs with a directory name as an argument, for example:
%emacs literature% emacs literatureEmacs 开始编辑文献 目录:您将看到一个包含文献 目录列表的窗口。您还可以使用Cx Cf(或任何其他用于访问文件的命令)并命名目录而不是文件来启动目录编辑器。例如,输入 Cx Cf 文献可以让您准备好编辑文献目录。键入Cx d(代表dired)或选择工具栏上的文件夹图标也会启动 Dired;然后指定一个目录名称。最后,将文件夹拖到 Emacs 窗口上也会启动 Dired。[ 2 ]
Emacs starts up editing the directory literature: you'll see a single window that contains a listing of the literature directory. You can also start the directory editor by using C-x C-f (or any other command for visiting a file) and naming a directory, rather than a file. For example, typing C-x C-f literature gets you ready to edit the literature directory. Typing C-x d (for dired) or selecting the folder icon on the toolbar also starts Dired; you then specify a directory name. Finally, dragging a folder onto the Emacs window also starts Dired.[2]
无论你如何启动编辑器,结果都是一样的。
No matter how you start the editor, the result is the same.
可以看到,Dired的显示是 类似于在 Unix shell 提示符下键入ls -l时看到的内容。权限 与文件关联的所有者、组名、文件大小和最后修改日期都位于文件名之前。列出所有文件和目录,包括名称以点开头的文件和目录。光标从文件名开始,而不是从第一列开始。
As you can see, Dired's display is similar to what you see if you type ls -l at a Unix shell prompt. The permissions associated with the file, the owner, the group name, the size of the file, and the date last modified all precede the filename. All files and directories are listed, including those whose names start with a dot. The cursor starts out on a filename, rather than in the first column.
另外,如果您的显示器支持 颜色(不幸的是本书没有),你会看到目录是蓝色的,备份和自动保存文件是棕褐色的,符号链接是紫色的。颜色是字体锁定模式的函数。如果您在目录列表中没有看到颜色,请输入Mx font-lock-mode Enter或将以下行添加到您的 .emacs文件中:
Also, if your display supports colors (unfortunately this book doesn't), you'll see that directories are blue, backup and auto-save files are tan, and symbolic links are purple. Colors are a function of font-lock mode. If you don't see colors in your directory listing, type M-x font-lock-mode Enter or add the following line to your .emacs file:
(全局字体锁定模式 t)
(global-font-lock-mode t)
默认情况下,列表
按文件名排序,但您可以按日期排序。查看模式线。它说(
Dired
by name
)。要更改显示顺序,请键入s(表示
dired-sort-toggle-or-edit)。此命令将最新文件放在列表顶部,解决“我昨天处理的文件在哪里?”的问题。问题很容易。模式行显示
(
Dired by
date
)。再次输入s可切换排序,将其恢复为按字母顺序排列。
By default, the list
is
sorted by filename, but you can sort it by date instead. Look at the
mode line. It says (
Dired
by name
). To change the
order of the display, type s (for
dired-sort-toggle-or-edit). This
command puts the newest files at the top of the list, solving the
"Where's that file I worked on
yesterday?" problem quite easily. The mode line says
(
Dired by
date
). Typing s again toggles the sort, putting it back in
alphabetical order.
如果您还记得用于编辑缓冲区列表的命令(来自第 4 章),您会发现它们与目录编辑器命令几乎相同。您可以执行许多其他操作,但基本命令是相同的。
If you remember the commands used to edit the buffer list (from Chapter 4), you will find that they are almost identical to the directory editor commands. You can do many additional things, but the basic commands are the same.
请记住,在目录编辑器中,您直接处理文件,而不是缓冲区。当您使用 Dired 删除文件时,该文件将永久消失。
Remember, in the directory editor you are working directly with files, not with buffers. When you delete a file using Dired, it's gone permanently.
在 Dired 中有多种移动方式。命令 Space、Cn和n 都会将您移至列表中的下一个文件。Del、Cp和 p都会将您移至上一个文件。箭头键以及PgUp和PgDown也可以使用。您还可以使用任何搜索命令(增量搜索、单词搜索等)来查找特定文件。
There are several ways to move around in Dired. The commands Space, C-n, and n all move you to the next file in the list. Del, C-p, and p all move you to the previous file. Arrow keys and PgUp and PgDown work as well. You can also use any of the search commands (incremental search, word search, and so on) to find a particular file.
当你查看目录时
列表中,您可能想快速浏览一下这些文件。 Dired 的v命令就是这样做的:将光标放在要查看的文件上,然后按v(对于dired-view-file)。 Emacs 以查看模式显示该文件。[ 3 ]这是只读模式,因此您无法修改该文件。按
抄送或q返回目录列表。查看文件时,可以使用s开始增量搜索,或按
Enter 键将显示内容向下滚动一行。键入=会告诉您光标位于哪一行。其他 Emacs 命令(例如标记文本)有许多快捷方式,但坦率地说,常规命令可以正常工作。当您已经知道的命令可以工作时,没有理由记住一组特殊的命令。
When you look at a directory
listing, you may want to get a quick
look at the files. Dired's v command does just this: put the cursor on
the file you want to view and press v (for dired-view-file). Emacs displays the file in
view mode.[3] This is a
read-only mode, so you can't modify the file. Press
C-c or q to return to the directory listing. While
you're viewing the file, you can use s to start an incremental search, or press
Enter to scroll the display down one
line. Typing = tells you what line the cursor
is on. There are a number of shortcuts for other Emacs commands (like
marking text), but frankly, the regular commands work correctly.
There's no reason to remember a special set of
commands when the ones you already know work.
如果要编辑 Dired 缓冲区中的文件,请移动到文件所在行并按Enter 键(也可以使用其他各种击键,例如f用于查找或e用于编辑)。 Emacs 找到该文件,您可以对其进行编辑。这是一个完全正常的编辑缓冲区:您可以进行任何所需的更改、保存它们、访问其他文件等等。键入 Cx b后跟您正在工作的目录名称,您将返回到 Dired 缓冲区。或者您可以使用缓冲区菜单 ( Cx Cb ) 查找并显示 Dired 缓冲区。
If you want to edit a file from the Dired buffer, move to the line the file is on and press Enter (a variety of other keystrokes work as well, such as f for find or e for edit). Emacs finds the file and you can edit it. This is a completely normal editing buffer: you can make any changes you want, save them, visit other files, and so on. Typing C-x b followed by the name of the directory you were working in moves you back to the Dired buffer. Or you can use the buffer menu (C-x C-b) to find and display the Dired buffer.
查看和编辑文件固然很好,但您已经知道如何做到这一点了,对吧?您正在等待有趣的内容:如何删除文件。
Viewing and editing files is nice, but you already know how to do that—right? You're waiting for the interesting stuff: how to delete files.
正如我们所说,文件删除几乎是 与使用缓冲区列表删除缓冲区相同。如果您了解了如何删除缓冲区,那么您就了解了使用 Dired 删除文件的基础知识。首先,通过移动到文件名并输入 d将文件标记为删除。执行此操作会在左边距放置一个D并将光标移动到列表中的下一个文件。您可以根据需要标记任意数量的文件。此时您可以改变主意并输入u来取消删除该文件。稍后,您键入x来删除文件(稍后将详细介绍)。以下屏幕显示了当您标记一些要删除的文件时 Dired 缓冲区的样子。
As we've said, file deletion is almost identical to buffer deletion with the buffer list. If you learned how to delete buffers, you know the basics of deleting files with Dired. First, you flag a file for deletion by moving to the file's name and typing d. Doing this places a D on the left margin and moves the cursor to the next file in the list. You can flag as many files as you want. You can change your mind at this point and type u to undelete the file. At some later time, you type x to delete the files (more on this in a minute). The following screen shows what the Dired buffer looks like when you flag a few files for deletion.
正如我们提到的,您可以随时键入u以从文件中删除删除标志。键入 u会将您移至列表中的下一个文件,如果已标记,则取消标记。您还可以使用Del取消标记。此命令取消删除 列表中的前一个文件,然后向上移动一行。
As we mentioned, you can type u at any time to remove the deletion flags from the files. Typing u moves you to the next file in the list, and, if it is marked, unmarks it. You can also use Del to unmark. This command undeletes the previous file in the list and then moves up one line.
因为 Emacs 生成
备份文件,有时自动保存文件,您可能不时需要删除它们。 Emacs 提供快捷命令来标记此类文件。键入会将#所有自动保存文件(名称以 开头和结尾的文件#)标记为删除。 Emacs 将它们标记为 D。键入~
会将所有备份文件(名称以~结尾)标记为删除。您可以从要保留的备份文件中删除标志,例如,您最近处理过的文件的备份副本。
Because Emacs generates
backup
files and, at times, auto-save files, you may want to delete them
from time to time. Emacs offers shortcut commands to flag such files.
Typing # flags all the auto-save files (files
whose names start and end with #) for
deletion. Emacs flags them with D. Typing ~
flags all the backup files (whose names end with ~) for deletion. You can remove the flags from
backup files you want to keep, for example, the backup copies of
files you've recently worked on.
当您确实希望从磁盘中删除文件时,请按x。 Emacs 显示所有标记为删除的文件的名称,并询问您是否要删除它们。
When you really want files to be deleted from disk, press x. Emacs displays the names of all the files flagged for deletion and asks you if you want to delete them.
|
类型:x Type: x |
|
|
|
Emacs 要求您输入yes (Windows)来确认删除。 Emacs asks you to confirm the deletion by typing yes (Windows). |
输入yes将它们全部删除,或者输入 no返回 Dired 缓冲区而不删除任何它们。
Type yes to delete them all or type no to return to the Dired buffer without deleting any of them.
这是删除文件的常用方法,但如果您想立即删除文件,请键入大写D。 Emacs 询问您是否要删除该文件 (是或否)。输入yes立即删除该文件,或 输入no改变主意。在 Dired 中,这是小写字母(如d表示删除标记)和大写字母(如D表示立即删除)具有不同含义的多种情况之一 。
This is the usual way of deleting files, but if you want a file deleted right away, type an uppercase D. Emacs asks if you want to delete the file (yes or no). Type yes to delete the file immediately or no to change your mind. In Dired, this is one of a number of cases in which the lowercase letter (like d to flag for deletion) and the uppercase letter (like D to delete immediately) have a different meaning.
要在 Dired 中复制文件,请在其旁边键入C(必须是大写 C)。 Emacs 询问您要复制到的文件的名称。输入名称并按Enter。 Emacs 说,Copied: 1
file.要复制列表中的多个文件,请在 C 前面加上数字。例如,输入3C
将复制该文件和接下来的两个文件。 (请参阅本章后面的“使用文件组”,了解选择要操作的文件组的更奇特的方法。)
To copy a file in Dired, type C next
to it (it must be a capital C). Emacs asks for the name of the file
you want to copy to. Type the name and press Enter. Emacs says, Copied: 1
file. To copy several files in the list, preface the C with
a number. For example, typing 3C
would copy this file and the next two files. (See
"Working with Groups of Files"
later in this chapter for fancier ways to select a group of files to
operate on.)
要使用 Dired 重命名文件(类似于 Unix mv命令),请在文件名旁边键入R。 Emacs 询问新名称应该是什么。键入它并按Enter。 Emacs 说,Moved: 1
file.
To rename a file with Dired (similar to the Unix mv command), type R next to the filename. Emacs asks what the
new name should be. Type it and press Enter. Emacs says, Moved: 1
file.
如果您在平台之间移动文件,则可能会出现一些文件名大写而另一些文件名小写的情况。例如,从旧版本 Windows 移动的文件可能全部大写。只需输入m标记有问题的文件,然后按%l(小写)或%u(大写)。瞧——无痛的案例一致性。
If you move files between platforms, you can wind up with some filenames in uppercase and some in lowercase. Files moving from older versions of Windows may be in all caps, for example. Simply mark the files in question by typing m, then press %l for lowercase or %u for uppercase. Voilà—painless case consistency.
压缩文件可以节省磁盘空间 空间,而 Dired 提供了一种简单的方法来做到这一点。将光标放在要压缩的文件的行上,然后按Z(表示dired-do-compress)。 Emacs 询问以下内容:
Compressing files saves disk space, and Dired provides an easy way to do it. Put the cursor on the line of the file you want to compress and press Z (for dired-do-compress). Emacs asks the following:
压缩还是解压缩filename? (y 或 n)Compress or uncompress filename? (y or n)如果文件未压缩,Emacs 将对其进行压缩;如果已压缩,则 Emacs 将其解压缩。[ 4 ]按y压缩或解压缩当前文件。压缩会立即发生,因此您可以在 Emacs 压缩文件时观察扩展名和文件大小的变化。
Emacs compresses the file if it's not compressed and uncompresses it if it is.[4] Press y to compress or uncompress the current file. Compression happens immediately, so you can watch both the extension and file size change as Emacs compresses the file.
编辑压缩文件怎么样?尽管默认情况下它没有打开,但 Emacs 有一个自动压缩/解压缩模式,称为自动压缩模式。要为此会话输入它,请键入 Mx auto-compress-mode Enter,这将打开自动压缩。要自动启用自动压缩,请将此行添加到您的.emacs 文件中:
What about editing compressed files? Although it's not on by default, Emacs has an automatic compression/decompression mode called auto-compress mode. To enter it for this session, type M-x auto-compress-mode Enter, which turns automatic compression on. To enable auto-compression automatically, add this line to your .emacs file:
(自动压缩模式 1)
(auto-compression-mode 1)
在第4章中,我们讨论了
比较两个窗口中的文件。 Emacs 提供了一种使用Dired 中的diff命令来执行此操作的方法。在要比较的文件上设置标记,将光标放在另一个文件上,然后输入=。 Emacs 比较两个文件并打开一个窗口,其中*diff*包含命令输出的缓冲区。
In Chapter 4, we discussed
comparing files in two windows. Emacs
provides a way to do this using the diff command in Dired. Set the mark on the
file you want diff to compare, put
the cursor on the other file, then type =. Emacs compares the two files and opens a
window with a *diff* buffer containing the output
from the command.
Emacs 有一个单独的选项用于将文件与其备份文件进行比较。将光标放在要与其备份进行比较的文件上,然后输入M-=。 Emacs 显示一个
*diff*缓冲区,显示两个文件之间的差异。
Emacs has a separate option for comparing a file to its backup file.
Put the cursor on the file you want to compare with its backup and
type M-=. Emacs displays a
*diff* buffer showing the differences between the
two files.
如果您认真对待版本控制,您可能需要查看 第 12 章,其中讨论了版本控制以及 GNU 工具ediff。
If you are serious about version control, you may want to check out Chapter 12, which discusses version control as well as the GNU tool ediff.
虽然迪雷德的 diff的实现很有用(并且还有chmod、grep和find的实现),从更一般的意义上来说,您可以通过按感叹号 ( ! ) 对文件执行任何命令。例如,让我们使用 sort命令按字母顺序排列电话列表文件。
While Dired's implementation of diff is useful (and there are implementations of chmod, grep, and find as well), in a more general sense, you can perform any command on a file by pressing an exclamation point (!). For example, let's alphabetize the phone list file using the sort command.
|
移至电话文件并按! Move to the phone file and press ! |
|
|
|
Emacs 询问您要运行什么命令 (Mac OS X)。 Emacs asks what command you want to run (Mac OS X). |
|
类型:排序 Type: sort |
|
|
|
Emacs 在单独的窗口 (Mac OS X) 中显示命令的输出。 Emacs displays the output from the command in a separate window (Mac OS X). |
通常,星号 (*) 和问题 标记在命令中用作通配符。在 Dired 中,它们有着特殊的意义。星号表示“使用我正在处理的文件或我已标记的文件”;这样您就不必显式键入文件名。当标记多个文件时,问号表示对每个文件分别运行该命令。
Usually, asterisks (*) and question marks are used as wildcards in commands. In Dired, they have a special meaning. An asterisk means "use the file I'm on or the files I've marked"; that way you don't have to type filenames explicitly. When multiple files are marked, a question mark means to run this command separately on each file.
在稍微复杂一点的示例中,您可能有一个带有多个文件作为参数的命令。例如,您可能想从已排序的电话列表中创建一个新文件。
In a slightly more complex example, you might have a command with more than one file as an argument. For example, you might want to make a new file out of the sorted phone list.
|
将光标移至电话文件,然后键入: ! Move the cursor to the phone file, then type: ! |
|
|
|
Emacs 询问您要运行什么命令 (Mac OS X)。 Emacs asks what command you want to run (Mac OS X). |
现在告诉 Emacs 你想要的 对您的 电话文件进行排序并将输出放入名为phonesorted的新文件中。光标位于 电话文件上,因此您无需在命令中键入其名称。用星号 (*) 替换文件名:
Now tell Emacs you want to sort your phone file and put the output in a new file called phonesorted. The cursor is on the phone file, so you don't need to type its name in the command. Substitute an asterisk (*) for the name of the file:
|
类型:排序 * > 电话排序 Type: sort * > phonesorted |
|
|
|
操作系统对phone文件进行排序,并将输出放入新文件phonesorted (Mac OS X) 中。 The operating system sorts the phone file and puts the output into the new file phonesorted (Mac OS X). |
我们创建了该文件,但它没有出现在显示屏上,在这种情况下显示屏不会自动更新。要查看 电话排序的文件,请输入g。
We created the file, but it doesn't appear on the display, which is not automatically updated in this case. To see the phonesorted file, type g.
|
类型:g Type: g |
|
|
|
Emacs 更新 Dired 显示,显示已排序的文件 (Mac OS X)。 Emacs updates the Dired display, showing the file phonesorted (Mac OS X). |
坦率地说,Dired 对于在显示更新之前是否键入g不一致。我们很快就会看到,有些命令会立即更新显示。其他的,例如对文件运行 shell 命令,则不会(Emacs 实际上不知道它正在运行哪些 shell 命令或它们对显示的影响)。一个好的经验法则是,如果您没有看到您期望看到的内容,请输入g 。
Dired is frankly inconsistent about whether you type g before the display is updated. Some commands, as we'll see shortly, update the display immediately. Others, such as running shell commands on files, do not (Emacs really doesn't know what shell commands it's running or their effect on the display). A good rule of thumb is to type g if you don't see what you expect to see.
到目前为止,我们已经讨论了一次处理一个文件;您给出的任何命令都适用于光标所在的文件。使用多个文件可以更好地说明 Dired 的真正威力。一旦你学会了一些快捷方式,你就可以快速组织你的目录。首先我们来谈谈选择文件的一些方法,然后我们将讨论我们可以对选定的文件做什么。
So far we've talked about working with one file at a time; any commands you give apply to the file the cursor is on. Working with multiple files is a better illustration of the real power of Dired. You can organize your directories in a flash once you learn a few shortcuts. First let's talk about some ways to select files, and then we'll talk about what we can do with the selected files.
到目前为止我们主要 讨论了标记要删除的文件。当您想对一组文件执行其他操作时,首先用星号标记它们。按 m标记光标所在的文件;通常看到 D 的位置会出现一个星号。键入3m标记此文件和接下来的两个文件。一旦您用星号标记文件,Emacs 就会假定您发出的任何命令都是针对这些文件的。因此,如果您有三个标有星号的文件并按Z进行压缩,Emacs 会假定您要压缩这三个文件。压缩后,文件仍带有星号标记。那么,当您处理完这些文件后,如何去掉星号呢?
So far we've primarily talked about flagging files for deletion. When you want to do something else with a group of files, you first mark them with an asterisk. Pressing m marks the file the cursor is on; an asterisk appears where you normally see a D. Typing 3m marks this file and the next two files. Once you mark files with an asterisk, Emacs assumes that any command you issue is meant for these files. So if you have three files marked with an asterisk and press Z to compress, Emacs assumes you want to compress those three files. After the compression, the files remain marked with asterisks. So how do you get rid of the asterisks when you're done with these files?
要删除星号,请按M-Del(对于dired-unmark-all-files)。 Emacs 询问要删除哪些标记。按Enter,Emacs 会删除所有标记。
To remove the asterisks, you press M-Del (for dired-unmark-all-files). Emacs asks which marks to remove. Press Enter, and Emacs removes all the marks.
有时,标记您不想使用的文件比标记您想要使用的文件更容易。按 t切换标记,标记所有未标记的文件并从先前标记的文件中删除标记。
Sometimes it's easier to mark the files you don't want to work with than those you do. Pressing t toggles the marks, marking all unmarked files and removing marks from those previously marked.
按顺序标记文件 很简单,但老实说,它并不是很强大。 Emacs 提供命令来选择清理目录时经常想要删除的文件类型:备份文件、自动保存文件和所谓的垃圾文件。
Marking files sequentially is simple but, in all honesty, it's not very powerful. Emacs provides commands for selecting types of files that you often want to get rid of when you're cleaning up a directory: backup files, auto-save files, and so-called garbage files.
自动保存的文件有
当会话异常终止时创建;他们有格式
。 Emacs 定期创建的备份文件的格式为
.要在 Dired 中标记这些文件,请分别键入#或
~。#
filename
#filename
~
Auto-save files are
created
when a session terminates abnormally; they have the format
#
filename
#.
Backup files which Emacs creates periodically, have the format
filename
~. To mark
these files in Dired, type # or
~ respectively.
Emacs 还有一个选项可以自动选择“垃圾”文件。默认情况下,这包括具有以下扩展名的文件: .log、.toc、 .dvi、.bak、 .orig和.rej。垃圾文件由正则表达式定义,该表达式包含在变量dired-garbage-files-regexp中;您可以更改此变量的值来定义您认为合适的垃圾文件(毕竟,一个人的垃圾是另一个人的宝藏)。
Emacs also has an option that automatically selects "garbage" files. By default, this includes files with the following extensions: .log, .toc, .dvi, .bak, .orig, and .rej. Garbage files are defined by a regular expression, which is contained in the variable dired-garbage-files-regexp; you can change the value of this variable to define garbage files as you see fit (after all, one man's junk is another man's treasure).
Dired 提供命令 用于选择可执行文件、目录和符号链接。要选择可执行文件,请键入**。要选择目录,请键入* /。键入* @标记符号链接。
Dired provides commands for selecting executable files, directories, and symbolic links. To select executable files, type * *. To select directories, type * /. Typing * @ marks symbolic links.
很多时候你想要选择 相关文件,然后对其进行存档、移动、压缩或直接删除。通常,您使用通配符来选择多个文件。在 Dired 中,您使用正则表达式。要标记文件名与正则表达式匹配的一组文件,请按%后跟 m以用星号标记它们。
Often you want to select related files and either archive them, move them, compress them, or just delete them. Typically, you use wildcards to select multiple files. In Dired, you use regular expressions. To mark a group of files whose filenames match a regular expression, press % followed by m to mark them with an asterisk.
例如,让我们标记所有以ch开头的文件。还记得第 3 章中有关正则表达式的快速课程吗?^查找单词的开头,因此正则表达式^ch将标记所有以ch开头的文件。
For example, let's mark all the files that start with ch. Remembering the quick lesson on regular expressions from Chapter 3, ^ finds the beginning of a word, so the regular expression ^ch would mark all the files that start with ch.
|
类型:%m Type: %m |
|
|
|
Emacs 需要一个正则表达式,以便它可以标记文件 (Windows)。 Emacs asks for a regular expression so that it can mark the files (Windows). |
|
输入:^ch 输入 Type: ^ch Enter |
|
|
|
Emacs 标记所有以ch开头的文件,并告诉您标记了多少个文件。 Emacs marks all the files starting with ch and tells you how many it marked. |
有时,标记内容与给定正则表达式匹配的文件更有用 。要标记包含特定正则表达式的文件,请键入% g,后跟要匹配的正则表达式(如果您熟悉grep ,请将g视为grep)。
Sometimes it's more useful to mark files whose contents match a given regular expression. To mark files that contain a certain regular expression, type % g, followed by the regular expression to match (think g for grep if you're familiar with grep).
现在我们已经标记了文件,让我们谈谈如何处理它们。
Now that we've got the files marked, let's talk about what to do with them.
在......的进程中 在日常工作中,目录可能会因许多不同类型的文件而变得混乱。最终,您需要创建子目录来按项目组织文件,然后将文件移动到这些子目录中。您可以在 Dired 中完成这两件事。
In the course of daily work, a directory can get cluttered with many different kinds of files. Eventually, you need to make subdirectories to organize the files by project, then move the files to those subdirectories. You can do both these things from within Dired.
假设ch文件是您在业余时间写的小说中的章节。我们需要一个名为novel的子目录来存储文件。您可以通过键入+创建一个目录(对于dired-create-directory)。
Let's say that the ch files are chapters from a novel you work on in your spare time. We need a subdirectory called novel to store the files in. You can create a directory by typing + (for dired-create-directory).
|
类型:小说 进入 Type: novel Enter |
|
|
|
Emacs 创建目录并将其显示在屏幕上 (Windows)。 Emacs creates the directory and displays it on the screen (Windows). |
现在让我们将标记的ch文件移动到新目录中。我们将使用重命名命令R。该命令与 Unix mv命令一样,用于重命名文件和移动文件。因为我们用星号标记了多个文件,所以当我们输入R时,Emacs 会假设我们要移动标记的文件。
Now let's move the ch files we marked into the new directory. We'll use the rename command, R. This command, like the Unix mv command, is used for renaming files and for moving them. Because we have marked more than one file with an asterisk, when we type R, Emacs assumes we mean to move the marked files.
|
类型:R Type: R |
|
|
|
Emacs 询问您要将标记的文件移至何处 (Windows)。 Emacs asks where you want to move the marked files to (Windows). |
现在您可以看到文件已移动。通过正则表达式标记文件使您可以快速处理选定的文件组。
Now you can see that the files have moved. Marking files by regular expression allows you to work with a select group of files quickly.
您可以对一组文件做的更有趣的事情之一是对所有文件执行查询替换 只需一个命令即可实现。在大型项目中,最后一刻的更改通常会迫使您对每个文件中的某些文本进行艰苦的搜索和替换。首先,选择要包含在查询替换中的文件,然后按Q(对于 dired-do-query-replace)。输入搜索字符串,然后输入替换字符串(字符串可以是纯文本或正则表达式),Emacs 会启动查询替换,依次浏览每个文件。这是唯一的问题:如果您通过递归编辑中断查询替换,则在不返回 Dired 缓冲区的情况下无法重新启动它。
One of the more interesting things you can do with a group of files is perform a query-replace on all of them with a single command. On large projects, a last-minute change often forces arduous searching and replacing of certain text in each file. First, select the files you want to include in the query-replace, then press Q (for dired-do-query-replace). Put in the search string, then the replacement string (the strings can be plain text or a regular expression) and Emacs starts a query-replace that moves you through each file sequentially. Here's the only hitch: if you interrupt the query-replace with a recursive edit, you can't restart it without going back to the Dired buffer.
另一个有趣的命令是跨文件搜索给定的正则表达式。为此,请标记文件,然后按A。 Emacs 在第一个匹配处停止;按 M-移动到下一场比赛。
Another interesting command is searching across files for a given regular expression. To do this, mark the files, then press A. Emacs stops at the first match; press M-, to move to the next match.
经常在打扫卫生的时候 向上目录,您可以在它们之间移动文件、组织子目录等等。这自然涉及到目录之间的大量移动。
Often when you are cleaning up directories, you're moving files between them, organizing subdirectories, and the like. This naturally involves a lot of moving among directories.
要移至您所在目录的父目录,请按^。要移动到缓冲区中的下一个目录,请按>;毫不奇怪,按<会将您移至缓冲区中的上一个目录。
To move to the parent directory of the one you're in, press ^. To move to the next directory in the buffer, press >; pressing <, not surprisingly, moves you to the previous directory in the buffer.
有时,在同一缓冲区中编辑目录及其子目录会更方便。要在当前 Dired 缓冲区中插入子目录,请移动到该子目录并按i。 Emacs 将子目录插入到缓冲区的末尾。如果以这种方式插入更多子目录,它们将按字母顺序出现在缓冲区的末尾。
Sometimes it's more convenient to edit a directory and its subdirectories in the same buffer. To insert a subdirectory in the current Dired buffer, move to it and press i. Emacs inserts the subdirectory at the end of the buffer. If you insert more subdirectories in this fashion, they will appear in alphabetical order at the end of the buffer.
正如您所看到的,您的大部分文件维护和清理工作都可以在 Dired 中轻松完成。表 5-2总结了 Dired 命令,其中一些我们还没有充分讨论。关于 Dired,还有更多东西需要了解,[ 5 ],但现在您已经了解了基础知识,您可以自己进行实验。
As you can see, much of your file maintenance and cleanup can be done easily from within Dired. Table 5-2 summarizes Dired commands, some of which we haven't fully discussed. There's more to learn about Dired,[5] but now that you know the basics, you can experiment on your own.
表 5-2。定向命令
Table 5-2. Dired commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
Cx d 文件 → 打开目录 C-x d File → Open Directory |
迪雷德 dired |
开始 Dired。 Start Dired. |
|
A 操作 → 搜索文件 A Operate → Search Files |
直接搜索 dired-do-search |
对标记的文件进行正则表达式搜索;在第一个匹配处停止; M-,查找下一个匹配项。 Do a regular expression search on marked files; stops at first match; M-, finds next match. |
|
B 操作 → 字节编译 B Operate → Byte-compile |
直接执行字节编译 dired-do-byte-compile |
字节编译文件。 Byte-compile file. |
|
C 操作 → 复制到 C Operate → Copy to |
直接复制 dired-do-copy |
复制文件。 Copy file. |
|
d 标记 → 旗帜 d Mark → Flag |
dired 标志文件删除 dired-flag-file-deletion |
标记为删除。 Flag for deletion. |
|
D 操作 → 删除 D Operate → Delete |
直接删除 dired-do-delete |
查询立即删除。 Query for immediate deletion. |
|
e e 立即 → 查找此文件 Immediate → Find This File |
dired 查找文件 dired-find-file |
编辑文件。 Edit file. |
|
F f |
dired-广告查找文件 dired-advertised-find-file |
查找(以便您可以编辑)。 Find (so you can edit). |
|
g 立即 → 刷新 g Immediate → Refresh |
恢复缓冲区 revert-buffer |
从磁盘重新读取目录。 Reread the directory from disk. |
|
G 操作 → 更改组 G Operate → Change Group |
dired-do-chgrp dired-do-chgrp |
更改组权限。 Change group permissions. |
|
H h |
描述模式 describe-mode |
显示 Dired 的描述性帮助文本。 Display descriptive help text for Dired. |
|
H 操作 → 硬链接到... H Operate → Hardlink to ... |
直接硬链接 dired-do-hardlink |
创建到该文件的硬链接; Emacs 要求您命名硬链接(并非所有操作系统都支持硬链接)。 Create a hard link to this file; Emacs asks you to name the hard link (not all OSes support hard links). |
|
i 子目录 → 插入此子目录.. i Subdir → Insert This Subdir ... |
可能插入子目录 dired-maybe-insert-subdir |
将此子目录的列表添加到当前的dired缓冲区中;如果它已经在那里,就移到它那里。 Add a listing of this subdirectory to the current dired buffer; if it's already there, just move to it. |
|
k k |
直接杀戮线 dired-do-kill-lines |
从显示中删除行(不删除文件)。 Remove line from display (don't delete file). |
|
L 操作 → 加载 L Operate → Load |
直接加载 dired-do-load |
加载文件。 Load file. |
|
m或* m 标记 → 标记 m or * m Mark → Mark |
迪雷德标记 dired-mark |
用*标记。 Mark with *. |
|
M 操作 → 改变模式 M Operate → Change Mode |
直接执行 chmod dired-do-chmod |
对此文件使用chmod命令。 Use chmod command on this file. |
|
n n |
定向下一行 dired-next-line |
移至下一行。 Move to next line. |
|
o 立即 → 在其他窗口中查找 o Immediate → Find in Other Window |
dired 查找文件其他窗口 dired-find-file-other-window |
在另一个窗口中查找文件;搬到那里。 Find file in another window; move there. |
|
Co 立即 → 在其他窗口中显示 C-o Immediate → Display in Other Window |
dired-显示文件 dired-display-file |
在另一个窗口中查找文件;不要搬到那里。 Find file in another window; don't move there. |
|
O 运营 → 变更所有者 O Operate → Change Owner |
迪雷多琼 dired-do-chown |
更改文件的所有权。 Change ownership of file. |
|
p p |
删除前一行 dired-previous-line |
向上移动一行。 Move up a line. |
|
P 操作 → 打印 P Operate → Print |
直接打印 dired-do-print |
打印文件。 Print file. |
|
q q |
退出窗口 quit-window |
退出迪雷德。 Quit Dired. |
|
Q 操作 → 文件中查询替换 Q Operate → Query Replace in Files |
直接执行查询替换 dired-do-query-replace |
查询标记文件中的替换字符串。 Query replace string in marked files. |
|
R 操作 → 重命名为 R Operate → Rename to |
直接重命名 dired-do-rename |
重新命名文件。 Rename file. |
|
S 操作 → 符号链接 S Operate → Symlink to |
直接执行符号链接 dired-do-symlink |
创建到该文件的符号链接; Emacs 要求您命名符号链接。 Create a symbolic link to this file; Emacs asks you to name the symbolic link. |
|
s s |
直接排序切换或编辑 dired-sort-toggle-or-edit |
按日期或按文件名对 Dired 显示进行排序(在这两者之间切换)。 Sort the Dired display by date or by filename (toggles between these). |
|
t 标记 → 切换标记 t Mark → Toggle Marks |
直接切换标记 dired-toggle-marks |
切换文件和目录上的标记;按一次t标记所有未标记的文件和目录;再次按t可恢复原始标记。 Toggle marks on files and directories; pressing t once marks all unmarked files and directories; pressing t again restores original marks. |
|
u 标记 → 取消标记 u Mark → Unmark |
取消标记 dired-unmark |
去除标记。 Remove mark. |
|
v 立即 → 查看此文件 v Immediate → View This File |
定向视图文件 dired-view-file |
查看文件(只读)。 View file (read-only). |
|
w w |
dired-copy-文件名-as-kill dired-copy-filename-as-kill |
将文件名复制到kill环中;如果标记了多个文件,则将所有标记文件的名称复制到杀环。 Copy filename into the kill ring; if multiple files are marked, copy names of all marked files to kill ring. |
|
X x |
直接执行标记删除 dired-do-flagged-delete |
删除带有D标记的文件。 Delete files flagged with D. |
|
y y |
dired-显示文件类型 dired-show-file-type |
使用file命令显示有关文件类型的信息。 Display information on the type of the file using the file command. |
|
Z 操作 → 压缩 Z Operate → Compress |
直接压缩 dired-do-compress |
压缩或解压缩文件。 Compress or uncompress file. |
|
~ 标记 → 标记备份文件 ~ Mark → Flag Backup Files |
dired-标志-备份文件 dired-flag-backup-files |
标记备份文件以供删除;Cu ~删除标志。 Flag backup files for deletion; C-u ~ removes flags. |
|
# 标记 → 标记自动保存文件 # Mark → Flag Auto-save Files |
dired-标志-自动保存文件 dired-flag-auto-save-files |
将自动保存文件标记为删除;Cu #删除标志。 Flag auto-save files for deletion; C-u # removes flags. |
|
& 标记 → 标记垃圾文件 & Mark → Flag Garbage Files |
dired-flag-垃圾文件 dired-flag-garbage-files |
标记“垃圾”文件以进行删除。 Flag "garbage" files for deletion. |
|
。标记 → 标记旧备份 .Mark → Mark Old Backups |
dired-clean-目录 dired-clean-directory |
标记要删除的编号备份(如果有)。 Flag numbered backups for deletion (if any). |
|
= 立即 → 差异 = Immediate → Diff |
直接差异 dired-diff |
将此文件与另一个文件(标记处的文件)进行比较。 Compare this file to another file (the one at the mark). |
|
M-= 立即 → 与备份比较 M-= Immediate → Compare With Backup |
直接备份差异 dired-backup-diff |
将此文件与其备份文件进行比较。 Compare this file with its backup file. |
|
!或 X 操作 → Shell 命令 ! or X Operate → Shell Command |
dired-do-shell 命令 dired-do-shell-command |
请求 shell 命令在当前文件或标记的文件上执行。 Ask for shell command to execute on the current file or marked files. |
|
+ 立即 → 创建目录 + Immediate → Create Directory |
dired 创建目录 dired-create-directory |
创建一个目录。 Create a directory. |
|
> 子目录 → 下一个目录 > Subdir → Next Dirline |
定向下一个定向 dired-next-dirline |
移至下一个目录。 Move to next directory. |
|
< 子目录 → 上一个目录 < Subdir → Prev Dirline |
迪雷-上一个-迪林 dired-prev-dirline |
移至上一个目录。 Move to previous directory. |
|
^ ^ |
目录 dired-up-directory |
在新的 Dired 缓冲区中查找父目录。 Find the parent directory in a new Dired buffer. |
|
$ 子目录 → 隐藏/取消隐藏子目录 $ Subdir → Hide/Unhide Subdir |
Dired-隐藏-子目录 dired-hide-subdir |
隐藏或显示当前目录或子目录。 Hide or show the current directory or subdirectory. |
|
M-$ 子目录 → 全部隐藏 M-$ Subdir → Hide All |
全部隐藏 dired-hide-all |
隐藏所有子目录,只保留它们的名称;重复命令即可显示。 Hide all subdirectories, leaving only their names; repeat command to show. |
|
CMn 子目录 → 下一个子目录 C-M-n Subdir → Next Subdir |
下一个子目录 dired-next-subdir |
移至下一个子目录(如果您已使用i插入子目录)。 Move to next subdirectory (if you've inserted subdirectories using i). |
|
CMp 子目录 → 上一个子目录 C-M-p Subdir → Prev Subdir |
dired-上一个子目录 dired-prev-subdir |
移至上一个子目录(如果您已使用i插入子目录)。 Move to previous subdirectory (if you've inserted subdirectories using i). |
|
CMu 子目录 → 树状结构 C-M-u Subdir → Tree Up |
干树向上 dired-tree-up |
如果您使用i插入了子目录,请移至此缓冲区中的父目录。 If you've inserted subdirectories using i, move to the parent directory in this buffer. |
|
CMd 子目录 → 树下 C-M-d Subdir → Tree Down |
干树倒下 dired-tree-down |
如果您已使用i插入子目录,请移至此缓冲区中该目录的第一个子目录。 If you've inserted subdirectories using i, move to the first subdirectory for this directory in this buffer. |
|
* c 标记 → 更改标记 * c Mark → Change Marks |
直接更改标记 dired-change-marks |
更改指定文件上的标记,例如,从*(通用标记)更改为D(标记为删除)。 Change marks on specified files, for example, from * (generic mark) to D (flagged for deletion). |
|
*!或 M-Del Mark → 全部取消标记 * ! or M-Del Mark → Unmark All |
dired-取消标记所有文件 dired-unmark-all-files |
删除所有文件中的所有标记。 Remove all marks from all files. |
|
* * 标记 → 标记可执行文件 * * Mark → Mark Executables |
Dired 标记可执行文件 dired-mark-executables |
标记可执行文件;Cu *取消标记。 Mark executables; C-u * unmarks. |
|
* / 标记 → 标记目录 * / Mark → Mark Directories |
直接标记目录 dired-mark-directories |
标记目录;铜 /未标记。 Mark directories; C-u / unmarks. |
|
* @ 标记 → 标记符号链接 * @ Mark → Mark Symlinks |
直接标记符号链接 dired-mark-symlinks |
标记符号链接;Cu * @取消标记。 Mark symlinks; C-u * @ unmarks. |
|
M-} 标记 → 下一个标记 M-} Mark → Next Marked |
下一个标记文件 dired-next-marked-file |
移至下一个标有* 或D 的文件。 Move to the next file marked with * or D. |
|
M-{ 标记 → 上一个标记 M-{ Mark → Previous Marked |
dired 上一个标记文件 dired-prev-marked-file |
移至上一个标有* 或D 的文件。 Move to previous file marked with * or D. |
|
%d 正则表达式 → 标志 % d Regexp → Flag |
dired-标志文件-regexp dired-flag-files-regexp |
删除与正则表达式匹配的文件的标志。 Flag for deletion files that match regular expression. |
|
% g 正则表达式 → 标记包含 % g Regexp → Mark Containing |
dired 标记文件包含正则表达式 dired-mark-files-containing-regexp |
标记内容与正则表达式匹配的文件。 Mark files whose contents match regular expression. |
|
% l 正则表达式 → 小写 % l Regexp → Downcase |
直接小写 dired-downcase |
小写标记的文件。 Lowercase marked files. |
|
% R 正则表达式 → 标记 % R Regexp → Mark |
dired 重命名正则表达式 dired-do-rename-regexp |
使用与正则表达式匹配的文件名重命名文件。 Rename files with filenames that match regular expression. |
|
% u 正则表达式 → 大写 % u Regexp → Upcase |
直接大写 dired-upcase |
大写标记的文件。 Uppercase marked files. |
[ 2 ]一个例外是在 Mac OS X 终端应用程序中运行 Emacs,它有自己的拖放行为。在终端中(以及在终端窗口中运行的 Emacs 中),拖放文件夹会插入该文件夹的完整路径名,而不是在 Dired 中打开该文件夹。
[2] The one exception to this is running Emacs in the Mac OS X Terminal application, which has its own drag-and-drop behavior. In the terminal—and thus in Emacs running in the terminal window—dragging and dropping a folder inserts the complete pathname of that folder rather than opening the folder in Dired.
[ 3 ]如果它是不应在 Emacs 中查看的文件(例如 JPG 或 PDF)怎么办?在这种情况下,变量dired-view-command-alist将查看器与文件扩展名相关联。此命令的默认值适用于 Linux,但在其他平台上需要进行一些调整。有关使用自定义更改 Mac OS X 和 Windows 变量的示例,请参阅第 10 章。
[3] What if it's a file that shouldn't be viewed in Emacs, like a JPG or a PDF? In this case, the variable dired-view-command-alist associates viewers with file extensions. The defaults for this command work on Linux, but require some tweaking on other platforms. See Chapter 10 for an example of using Custom to change this variable for Mac OS X and Windows.
[ 4 ] Emacs 仅理解 压缩和gzip格式,而不理解 ZIP 或其他专有文件压缩算法。当您解压缩文件时,Emacs 会识别并正确解压缩具有以下后缀的文件:.z、.Z或 .gz。当您压缩文件时,Emacs 使用 gzip,生成以 .gz结尾的文件。
[4] Emacs understands only compress and gzip formats, not ZIP or other proprietary file compression algorithms. When you uncompress files, Emacs recognizes and correctly uncompresses files with the following suffixes: .z, .Z, or .gz. When you compress files, Emacs uses gzip, resulting in files that end in .gz.
[ 5 ]如果所有 Dired 功能还不够,还有 Dired-x,这是一个附加模块,其中包含其他功能,例如从列表中省略不重要的文件、查找任何缓冲区中提到的文件以及附加变量和方法标记文件。有关更多详细信息,请参阅有关此主题的信息文本(键入Ch i进入信息菜单)。
[5] And if all the Dired features aren't enough, there's Dired-x, an add-in module that includes other features such as omitting unimportant files from the listing, finding files mentioned in any buffer, and additional variables and means of marking files. For more details, see the Info text on this subject (type C-h i to get to the Info menu).
Emacs 提供了几个命令 用于打印缓冲区和区域。要打印包含页码和文件名标题的缓冲区,请键入Mx print-buffer Enter。该命令将缓冲区发送到pr(一个对列表进行简单格式化的程序),然后是lpr(将列表发送到打印机)。如果您想直接打印文件,而不需要pr提供的标题和页码,请输入命令Mx lpr-buffer Enter。您还可以使用这些命令打印文件的选定部分。首先通过在一端设置标记并将光标移动到另一端来定义一个区域。然后输入命令Mx print-region Enter(或Mx lpr-region Enter)。
Emacs offers several commands for printing buffers and regions. To print a buffer with page numbers and headers for the filename, type M-x print-buffer Enter. This command sends the buffer to pr (a program that does simple formatting for listings), followed by lpr (which sends the listing to the printer). If you want to print the file directly, without the headers and page numbers that pr provides, give the command M-x lpr-buffer Enter. You can also use these commands to print a selected portion of a file. First define a region by setting a mark at one end and moving the cursor to the other end. Then give the command M-x print-region Enter (or M-x lpr-region Enter).
lpr -buffer和lpr-region命令
始终检查变量lpr-switches以确定是否应将任何选项传递给 Unix lpr
命令。这些选项用于请求特定的打印机以及许多其他目的;有关详细信息,请参阅lpr 的联机帮助页。例如,如果您希望每次从 Emacs 打印时都使用名为 lpt1 的打印机,则需要将lpr 开关设置为 - Plpt1。为此,请将以下行添加到您的
.emacs文件中:
The lpr-buffer and lpr-region commands
always check the variable lpr-switches to determine whether any options
should be passed to the Unix lpr
command. These options are used to request a particular printer and
for many other purposes; see the manpage for lpr for more information. For example, if you
want to use the printer named lpt1 whenever you print from Emacs, you
would want to set lpr-switches to
-Plpt1. To do so, add the following line to your
.emacs file:
(setq lpr-开关'(“-Plpt1”))
(setq lpr-switches '("-Plpt1"))请注意字符串“”前面的单引号和括起来的括号-Plpt1。这只是奇怪但必要的 Lisp 语法;详细信息请参见第 11 章。
Note the single quote preceding, and the parentheses surrounding, the
string "-Plpt1". This is just weird-but-necessary Lisp
syntax; see Chapter 11 for more details.
您还可以从 Dired 进行打印。要打印光标所在的文件,请键入P。 Emacs 将默认的打印命令放在迷你缓冲区中,您可以对其进行修改。
You can also print from Dired. To print the file the cursor is on, type P. Emacs puts the default printing command in the minibuffer, and you can modify it.
Emacs 还包括将缓冲区打印为 PostScript 文件的命令。如果您已格式化文件中的文本,则可以通过键入Mx ps-print-buffer-with-faces 来打印具有这些属性的缓冲区。
Emacs also includes commands to print a buffer as a PostScript file. If you have formatted text in the file, you can print the buffer with those attributes by typing M-x ps-print-buffer-with-faces.
表 5-3提供了打印命令的摘要。
Table 5-3 provides a summary of commands for printing.
表 5-3。打印命令
Table 5-3. Printing commands
|
击键 Keystrokes |
行动 Action |
|---|---|
|
Mx 打印缓冲区 文件 → 打印缓冲区 M-x print-buffer File → Print Buffer |
打印缓冲区(类似于 Unix pr | lpr)。 Print the buffer (similar to Unix pr | lpr). |
|
Mx 打印区域 文件 → 打印区域 M-x print-region File → Print Region |
打印区域(类似于 Unix pr | lpr)。 Print the region (similar to Unix pr | lpr). |
|
Mx lpr 缓冲区 M-x lpr-buffer |
没有页码的打印缓冲区(类似于 Unix lpr)。 Print buffer with no page numbers (similar to Unix lpr). |
|
Mx lpr 区域 M-x lpr-region |
打印没有页码的区域(类似于 Unix lpr)。 Print region with no page numbers (similar to Unix lpr). |
|
P 操作 → 打印 P Operate → Print |
从 Dired 中,将默认的打印命令放入迷你缓冲区中;您可以更改它或按Enter执行它。 From Dired, put the default print command in the minibuffer; you can change it or press Enter to execute it. |
|
Mx ps-print-buffer-with-faces 文件 → Postscript 打印缓冲区 M-x ps-print-buffer-with-faces File → Postscript Print Buffer |
打印带有文本属性的缓冲区。 Print the buffer with text attributes. |
|
Mx ps-print-region-with-faces 文件 → Postscript 打印区域 M-x ps-print-region-with-faces File → Postscript Print Region |
打印带有文本属性的区域。 Print the region with text attributes. |
你可以在线阅读Unix 通过键入Mx man或从“帮助”菜单中选择“Man” ,可以在 Emacs 中查看文档(称为 联机帮助页) 。[ 6 ]此命令创建一个缓冲区,其中包含格式化的联机帮助页,您可以使用 Emacs 命令滚动浏览(或从中复制)。只需输入:Mx man Enter Unix-command-name Enter。
You can read Unix online documentation (called manpages) from within Emacs by typing M-x man or by selecting Man from the Help menu.[6] This command creates a buffer with a formatted manpage in it, which you can scroll through (or copy from) using Emacs commands. Simply type: M-x man Enter Unix-command-name Enter.
对于 Unix 命令名称,您可以使用简单名称(如 ls)或手册页部分名称(如 ttytab(5) )。
For the Unix command name, you can use either a simple name, like ls, or a manpage section name like ttytab(5).
使用man命令的优点 是,与在某些终端应用程序或 shell 窗口中相比,您可以更轻松地滚动浏览联机帮助页。另外,如果您尝试在 shell 模式下查看联机帮助页,如果设置不正确,它们可能会出现乱码,而man会为您提供干净的文本。
The advantage of using the man command is that you can scroll through the manpage easier than you can in some terminal applications or shell windows. Also, if you try to view manpages in shell mode, they may come out garbled if the settings aren't right, whereas man gives you clean text.
Emacs 是组织所有工作的天然场所。它不会取代您的 Palm 或其他手持设备,但该领域正在进行的工作可能会帮助您将您喜爱的设备与基于 Emacs 的日程安排同步。这里我们介绍 Emacs 本身提供的主要功能——日历和日记。
Emacs is a natural place to organize all your work. It won't replace your Palm or other handheld, but ongoing work in this area may help you sync your favorite device with your Emacs-based schedule. Here we cover the main features that Emacs itself offers—the calendar and the diary.
要显示日历, 输入 Mx 日历。 Emacs 显示一个包含三个月的日历窗口:上个月、本月和下个月。
To display the calendar, type M-x calendar. Emacs displays a calendar window with three months: last month, this month, and next month.
|
类型:MX 日历 Type: M-x calendar |
|
|
|
Emacs 将光标放在今天的日期上并在模式行上显示该日期。日历上没有空间可写;这就是日记的用途,我们稍后会讨论。 Emacs puts the cursor on today's date and displays the date on the mode line. There's no room to write on the calendar; that's what the diary is for, which we'll discuss shortly. |
默认情况下,周开始 在星期天。如果您希望它们从星期一开始,请输入Mx set-variable calendar-week-start Enter 1 Enter。您再次输入日历以使此生效。如果您希望日历始终从星期一开始,请将此行添加到您的.emacs文件中:
By default, weeks start on Sunday. If you'd like them to start on Monday instead, type M-x set-variable calendar-week-start Enter 1 Enter. You enter the calendar again to have this take effect. If you'd like to have the calendar always start on Monday, add this line to your .emacs file:
(setq 日历-周-开始-日 1)
(setq calendar-week-start-day 1)
如果您想在每次启动 Emacs 时查看日历,可以将此行添加到您的 .emacs文件中:
If you'd like to see the calendar each time you start Emacs, you can add this line to your .emacs file:
(日历)
(calendar)
当您在日历中时,Emacs 白天明智地行动,而不是性格。CF带你到第二天;Cb将您移至前一天。Cn将您移至下周的同一天;CP让你倒退一周。箭头键的工作方式相同。M-} 和M-{按月向前和向后移动,Cx [和Cx ]按年向前和向后移动。 简历向前滚动三个月; mv回溯三个月。
When you're in the calendar, Emacs sensibly moves by day rather than by character. C-f moves you to the next day; C-b moves you to the previous day. C-n moves you to the same day of the next week; C-p moves you back a week. The arrow keys work the same way. M-} and M-{ move forward and backward by month, and C-x [ and C-x ] move forward and backward by year. C-v scrolls forward by three months; M-v scrolls back three months.
刚刚讨论的移动命令使您相对于光标位置移动。如果您在星期二按 Cn,您将移至下星期二。如果您在 1 月 25 日按下 M-},您将移至 2 月 25 日。如果您在 2004 年 8 月 15 日按下 Cx [,您将移至 2003 年 8 月 15 日。
The movement commands just discussed move you relative to the cursor position. If you're on Tuesday and you press C-n, you'll move to next Tuesday. If you're on January 25 and press M-} you'll move to February 25. If you're on August 15, 2004 and press C-x [, you'll move to August 15, 2003.
其他命令移动到周、月或年的开始或结束。Ca和Ce移动到周的开始和结束, Ma移动到月初,M-<移动到年初。表 5-4总结了这些日历移动命令。
Other commands move to the beginning or the end of the week, month, or year. C-a and C-e move to the beginning and end of the week, M-a moves to the beginning of the month, and M-< moves to the beginning of the year. Table 5-4 summarizes these calendar movement commands.
要转到特定日期,请按g d。 Emacs 要求输入年份,然后是月份,然后是日期。 Emacs 将您移至选定的日期(此命令非常适合回答这个非常重要的问题,“2020 年我的生日是一周中的哪一天?”)。
To go to a particular date, press g d. Emacs asks for the year, then the month, and then the day. Emacs moves you to the day selected (this command is well-suited for answering that all-important question, "On what day of the week does my birthday fall in 2020?").
表 5-4。日历移动命令
Table 5-4. Calendar movement commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
(无) 工具 → 显示日历 (none) Tools → Display Calendar |
日历 calendar |
显示日历。 Display the calendar. |
|
。前往 → 今天 .Goto → Today |
日历-转到今天 calendar-goto-today |
移至今天的日期。 Move to today's date. |
|
CF C-f |
日历向前日 calendar-forward-day |
前进一天。 Move forward a day. |
|
镉 C-b |
日历向后天 calendar-backward-day |
向后移动一天。 Move backward a day. |
|
中文 C-n |
日历向前一周 calendar-forward-week |
前进一周。 Move forward a week. |
|
CP C-p |
日历向后一周 calendar-backward-week |
向后移动一周。 Move backward a week. |
|
M-} M-} |
日历向前月份 calendar-forward-month |
前进一个月。 Move forward one month. |
|
M-{ M-{ |
日历向后月份 calendar-backward-month |
向后移动一个月。 Move backward a month. |
|
Cx ] 滚动 → 向前 1 年 C-x ] Scroll → Forward 1 Year |
日历向前年份 calendar-forward-year |
前进一年。 Move forward a year. |
|
Cx [ 滚动 → 向后 1 年 C-x [ Scroll → Backward 1 Year |
日历向后年份 calendar-backward-year |
向后移动一年。 Move backward a year. |
|
Ca Goto → 本周初 C-a Goto → Beginning of Week |
日历一周开始 calendar-beginning-of-week |
移至本周初。 Move to the beginning of the week. |
|
Ce Goto → 周末 C-e Goto → End of Week |
日历-周末 calendar-end-of-week |
移至本周末。 Move to the end of the week. |
|
后 岛真 → 月初 M-a Goto → Beginning of Month |
日历月初 calendar-beginning-of-month |
移至月初。 Move to the beginning of the month. |
|
我 转到 → 月底 M-e Goto → End of Month |
日历月末 calendar-end-of-month |
移至月底。 Move to the end of the month. |
|
M-< 转到 → 年初 M-< Goto → Beginning of Year |
日历年初 calendar-beginning-of-year |
移至年初。 Move to the beginning of the year. |
|
M-> 转到 → 年末 M-> Goto → End of Year |
日历年末 calendar-end-of-year |
移至年底。 Move to the end of the year. |
|
gd 转到 → 其他日期 g d Goto → Other Date |
日历转到日期 calendar-goto-date |
前往指定日期。 Go to the specified date. |
|
哦 o |
日历其他月份 calendar-other-month |
将指定的月份放在显示的中间。 Put the specified month in the middle of the display. |
|
Cx < 滚动 → 向前 1 个月 C-x < Scroll → Forward 1 Month |
向左滚动日历 scroll-calendar-left |
向前滚动一个月。 Scroll forward one month. |
|
Cx > 滚动 → 向后 1 个月 C-x > Scroll → Backward 1 Month |
向右滚动日历 scroll-calendar-right |
向后滚动一个月。 Scroll backward one month. |
|
简历 滚动 → 向前 3 个月 C-v Scroll → Forward 3 Months |
向左滚动日历三个月 scroll-calendar-left-three-months |
向前滚动三个月。 Scroll forward three months. |
|
Mv 卷轴 → 向前 3 个月 M-v Scroll → Forward 3 Months |
向右滚动日历三个月 scroll-calendar-right-three-months |
向后滚动三个月。 Scroll backward three months. |
|
空间 Space |
滚动其他窗口 scroll-other-window |
滚动另一个窗口。 Scroll another window. |
大家进入正题吧 感兴趣的是: 假期。要显示您正在查看的日历部分的假期,请键入a(对于 list-calendar-holidays)或 从“假期”菜单中选择“3 个月”。
Let's move to a topic everyone is interested in: holidays. To display the holidays for the part of the calendar you are looking at, type a (for list-calendar-holidays) or select 3 Months from the Holidays menu.
正如您所看到的,Emacs 知道相当多的假期,或者用它的话说,“重要的日期”。如果您在日历上的其他位置但想要查看当月附近的假期,请输入 Mxholidays。 Emacs 列出了它们。要查看今天是否是假期,请键入h或从“假期”菜单中选择“一天” 。
As you can see, Emacs knows about a fairly wide variety of holidays or, as it calls them, "notable dates." If you are somewhere else on the calendar but want to see holidays surrounding the current month, type M-x holidays. Emacs lists them. To see whether today is a holiday, type h or select One Day from the Holidays menu.
键入x以特殊方式标记假期,通常以粉红色突出显示它们。如果显示不支持此功能,Emacs 会在日期右侧添加一个星号。键入u会删除标记。
Typing x marks holidays in a special way, typically highlighting them in pink. If the display doesn't support this, Emacs puts an asterisk to the right of the date. Typing u removes the marks.
我们只教了您日历命令的基本框架。 Emacs 可以告诉您日出、日落和月相。您可以选择其他日历,例如伊斯兰历、希伯来历、玛雅历,甚至法国大革命历。但我们会把这些留给你去探索。
We have taught you only the bare bones of the calendar commands. Emacs offers to tell you sunrise and sunset and phases of the moon. You can choose other calendars, like the Islamic calendar, the Hebrew calendar, the Mayan calendar, or even the French Revolutionary calendar. But we will leave these for you to explore.
更多日历命令在日记上下文中使用,如下所述。
More calendar commands are used in the context of the diary, discussed next.
日记与日历密切相关,可以让您记录某些日期。您可以输入完整的每日时间表或仅标记重大事件。详细程度完全取决于您。
The diary, closely related to the calendar, allows you to make notes about certain dates. You can enter a full daily schedule or just mark major events. The level of detail is entirely up to you.
要使用日记,您 必须有一个 日记文件,其中包含有关重要事件或要做的事情的注释。它可以提醒您每周四备份系统、您每两周发一次工资、您在 7 月的前两周休假,或者您母亲的生日是 8 月 6 日。
To use the diary, you must have a diary file that contains notations about important events or things to do. It can remind you to back up your system every Thursday, that you get paid every two weeks, that you're on vacation during the first two weeks in July, or that your mother's birthday is August 6.
该文件必须称为diary,并且必须存在于您的主目录中。在此文件中,您可以插入几行(或者让 Emacs 为您编写几行)来记下您想要记住的日期。日记文件不必全部采用一种格式,也不必按任何特定顺序排序。日期格式可以混合使用:December 19, 2004 可以是 12/19/04、Dec 19 04 或 dec 19 2004。以下是日记文件中的几行,用于说明我们的意思。
The file must be called diary and must exist in your home directory. In this file, you insert lines—or have Emacs write lines for you—that note dates you want to remember. The diary file need not be all in one format and need not be sorted in any particular order. Date formats can be mixed: December 19, 2004 could be 12/19/04, Dec 19 04, or dec 19 2004. Here are a few lines from a diary file to illustrate what we mean.
11/14 我的生日 2004年7月17日 公司野餐 2004 年 3 月 18 日 年度报告到期 2004 年 1 月 8 日 头发预约 与伊丽莎白女王的周六茶会 周五发薪日
11/14 My birthday July 17 2004 Company picnic March 18 2004 Annual report due January 8 2004 Hair appointment &Saturday Tea with Queen Elizabeth Friday Payday
如果您不指定年份,Emacs 会假设您希望每年标记该日期,如生日。如果您不指定日期,而仅指定一周中的某一天(如星期六与女王喝茶),Emacs 将在每个星期六显示日记条目。在条目之前放置一个与号 (&) 会告诉 Emacs 不要在日历上标记它(您不希望每个星期六都被标记,并且您可能不希望每个人都知道您与皇室在一起)。
If you don't specify a year, Emacs assumes you want to mark that date every year, as in birthdays. If you don't specify a date but only the day of the week (as in tea with the queen on Saturday), Emacs displays the diary entry every Saturday. Putting an ampersand (&) before an entry tells Emacs not to mark it on the calendar (you don't want every Saturday marked, and you may not want everyone to know that you hang around with the royal family).
日期格式可以混合使用,但必须在创建日记之前选择使用欧洲日期格式(DD/MM/YYYY 或 2004 年 10 月 9 日)还是默认的美国日期格式(MM/DD/YYYY 或 2004 年 10 月 9 日) 文件。要指定欧洲日期格式,请将此行添加到您的.emacs文件中:
Date formats can be mixed, but the choice to use European date format (DD/MM/YYYY or 9 October 2004) versus the default American format (MM/DD/YYYY or October 9, 2004) must be made before you create the diary file. To specify European date format, add this line to your .emacs file:
(setq european-calendar-style 't)
(setq european-calendar-style 't)
你可以自己写
条目或让 Emacs 帮助您将其放入。要让 Emacs 帮助您,请输入Mx calendar转到日历
。然后按gd指定您要移至的日期。按id(用于插入日记条目)。 Emacs 将您转到写有日期的日记窗口。然后,您可以在日期旁边记下日记。如果您的条目跨越多行,请以一个空格开始第二行和后续行,以便 Emacs 理解它是延续。在您记下日期后,Emacs 会将您留在缓冲区中,
diary以便您可以输入更多条目。键入
Cx b以移动到另一个缓冲区。
You can write your own
entries or have Emacs help you put
them in. To have Emacs help you, go to the calendar by typing
M-x calendar. Then press g d to specify the date you want to move to.
Press i d (for insert-diary-entry). Emacs moves you to the
diary window with the date written out. You can then make a diary
entry next to the date. If your entry spans more than one line, begin
the second and subsequent lines with a single space, so that Emacs
understands it's a continuation. After you make the
notation about the date, Emacs leaves you in the
diary buffer so you can make more entries. Type
C-x b to move to another buffer.
insert-diary-entry命令假设您想要创建一个一次性条目。要创建重复条目,您需要更多命令。要插入每周条目,请输入iw。 Emacs 将您移至diary写有星期几的缓冲区。输入每周活动(例如员工会议),然后保存
日记文件。要插入年度条目,请输入
iy。 Emacs 将您移至
diary写有日期和月份的缓冲区;输入年度事件。对于周年纪念日有一个更具体的命令。输入ia添加周年纪念日;该条目包括年份(尽管我们还没有看到将此信息用于任何特定目的的函数,例如计算这是哪个周年纪念日)。
The insert-diary-entry command
assumes you want to make a single, one-time entry. To create a
recurring entry, you need a few more commands. To insert a weekly
entry, type i w. Emacs moves you to
the diary buffer with the day of the week written
out. Type the weekly activity (such as a staff meeting), and save the
diary file. To insert an annual entry, type
i y. Emacs moves you to the
diary buffer with the day and month written out;
type the annual event. There is a more specific command for
anniversaries. Type i a to add an
anniversary; this entry includes the year (though we have not seen a
function that uses this information for any particular purpose, such
as counting which anniversary this is).
你也可以把
在循环日记条目中,定期发生的条目,例如每三个月更换汽车机油的提醒。为此,请移至您上次更换机油的日期并输入i c。 Emacs 说:Repeat every how many
days: 然后您输入换油间隔的天数。 Emacs 编写了一个 Lisp 函数来处理这个问题并将其放入
diary缓冲区中。然后,您可以在 Lisp 函数旁边做一个注释,例如告诉您更换机油的注释。 Emacs插入的条目看起来像这样(我们把换油的部分放在我们自己里面):
You can also put
in cyclic diary
entries, entries that occur at regular intervals, like reminders to
change the oil in your car every three months. To do so, move to the
date you changed your oil last and type i
c. Emacs says, Repeat every how many
days: and you type the number of days between oil changes.
Emacs writes a Lisp function to handle this and puts it in the
diary buffer. You can then make a notation next to
the Lisp function, such as a note that tells you to change the oil.
The entry that Emacs inserts looks like this (we put the part about
changing the oil in ourselves):
%%(二循环 90 12 23 2004) 更换机油
%%(diary-cyclic 90 12 23 2004) Change the oil
条目上写着,从我们插入条目之日(2004 年 12 月 23 日)算起,每 90 天,我们应该更换汽车的机油。
The entry says that every 90 days, counting from the day we inserted the entry, December 23, 2004, we should change the oil in our car.
您可以标记一个日期块,例如为期一周的会议或假期。将光标放在第一个日期上,然后按C-空格键设置标记。[ 7 ]移动(使用日历移动命令,如Cf、Cn等)到第二个日期,然后按i b。 Emacs 将您移至diary缓冲区并插入一个咒语来标记日历上的星期。在 Emacs 插入的 Lisp 函数后面做一个注释。该条目看起来像这样:
You can mark a block of dates, as in the
case of a week-long conference or a vacation. Put the cursor on the
first date and press C-Space to set
the mark.[7] Move
(using calendar movement commands like C-f, C-n, and
so on) to the second date and press i
b. Emacs moves you to the diary buffer
and inserts an incantation that marks the week on your calendar. Make
a notation following the Lisp function Emacs inserts. The entry will
look something like this:
%%(日记块 3 15 2004 3 20 2004) 阿拉巴马州之旅
%%(diary-block 3 15 2004 3 20 2004) Trip to Alabama
此条目表示3月15日至3月20日,我们将去阿拉巴马州旅行。
This entry indicates that from March 15 to March 20, we'll go on a trip to Alabama.
如果您想注意必须在每月十五号提交费用报告怎么办? Emacs 接受月份的星号通配符 (*),正如您在键入i m时看到的那样(对于insert-monthly-diary-entry)。 Emacs 在月份位置插入一个星号,后接日期,如* 15中所示,表示安排在每月 15 日进行的活动。与往常一样,您在条目后做笔记。
What if you want to note that you have to file your expense report on the fifteenth of every month? Emacs accepts the asterisk wildcard (*) for the month, as you will see when you type i m (for insert-monthly-diary-entry). Emacs inserts an asterisk in place of the month, followed by the day, as in * 15 for something scheduled for the fifteenth of each month. As always, you make a note following the entry.
现在您已经了解了 Emacs 如何构建日记条目,您可以尝试根据 Emacs 所做的事情编写一些自己的日记条目。毕竟, 日记文件与任何其他 Emacs 文件一样;您可以随意进行更改、添加行和删除行。唯一的要求是完成后保存文件。现在让我们看看如何在适当的日期显示日记条目。
Now that you see how Emacs constructs diary entries, you can try writing some of your own based on what Emacs has done. After all, the diary file is like any other Emacs file; you can make changes, add lines, and delete lines at will. The only requirement is that you save the file when you're through. Now let's see how to display diary entries on the appropriate dates.
如果您想查看 给定日期的日记条目, 在日历中按d 。要查看整个日记文件,请在日历中按s 。如果您希望在启动 Emacs 时自动显示今天的日记条目,请将此行添加到您的.emacs 文件中:
If you want to review the diary entries for a given date, press d from the calendar. In order to see the whole diary file, press s from the calendar. If you want today's diary entries to display automatically when you start Emacs, add this line to your .emacs file:
(日记)
(diary)
这样,当您在有日记条目的一天启动 Emacs 时,日记条目会自动显示。例如,假设您不久前为最好的朋友庆祝了生日,而今天就是这一天。当您启动 Emacs 时,屏幕将如下所示:
That way, when you start up Emacs on a day for which there is a diary entry, the diary entry displays automatically. For example, let's say you marked your best friend's birthday some time ago, and today is the day. When you start Emacs, the screen would look like this:
|
你启动 Emacs。 You start Emacs. |
|
|
|
Emacs 显示您朋友生日的日记条目。 Emacs displays the diary entry for your friend's birthday. |
如果某一天没有日记条目,则不会显示日记。如果您以两个文件启动 Emacs,以便在两个窗口中进行编辑,则日志也不会显示。
If there are no diary entries for a given day, the diary is not displayed. If you start Emacs with two files so that you are editing in two windows, the diary is also not displayed.
如果您已在.emacs文件中 放入(日历)条目以自动显示日历,则日历将取代日记,如果您更喜欢查看日记,则必须删除日历。
If you have already put in a (calendar) entry in your .emacs file to have the calendar displayed automatically, the calendar supersedes the diary, and you'll have to remove the calendar if you prefer to see the diary instead.
要将日记条目标记为红色的日期,请在日历中按m 。要删除标记,请按u。 (此命令删除日记条目和假期的突出显示。)
To mark dates with diary entries in red, press m from the calendar. To remove the marks, press u. (This command removes highlighting for diary entries as well as for holidays.)
表 5-5总结了日历和日记命令。
Table 5-5 summarizes the calendar and diary commands.
表 5-5。假期和日记命令
Table 5-5. Holiday and diary commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
PD p d |
日历打印日期 calendar-print-day-of-year |
显示今年的第几天(例如,365 年的第 364 天)。 Display the day of the year this is (for example, Day 364 of 365). |
|
婆 p o |
日历打印其他日期 calendar-print-other-dates |
显示所有日历中有关该日期的信息。 Display information about this date for all calendars. |
|
空间 Space |
滚动其他窗口 scroll-other-window |
滚动另一个窗口。 Scroll the other window. |
|
q q |
退出日历 exit-calendar |
退出日历。 Quit calendar. |
|
a 假期 → 对于窗口 a Holidays → For Window |
列表日历假期 list-calendar-holidays |
显示所示日历期间的假期。 Display holidays for calendar period shown. |
|
h 假期 → 对于光标日期 h Holidays → For Cursor Date |
日历光标假期 calendar-cursor-holidays |
在迷你缓冲区中,显示光标所在日期的假期信息。 In the minibuffer, display holiday information for the day the cursor is on. |
|
x 假期 → 马克 x Holidays → Mark |
标记日历假期 mark-calendar-holidays |
以不同的字体、颜色或旁边带有星号显示假期。 Display holidays in a different typeface, color, or with an asterisk beside them. |
|
u 假期 → 取消日历标记 u Holidays → Unmark Calendar |
日历取消标记 calendar-unmark |
删除假期和日记条目的标记(与x命令相反)。 Remove marks for holidays and diary entries (opposite of x command). |
|
iw 日记 → 插入每周 i w Diary → Insert Weekly |
插入每周日记条目 insert-weekly-diary-entry |
根据星期几添加每周条目。 Add a weekly entry based on the day of the week. |
|
iy 日记 → 插入每年 i y Diary → Insert Yearly |
插入每年日记条目 insert-yearly-diary-entry |
添加年度条目。 Add an annual entry. |
|
id 日记 → 插入每日 i d Diary → Insert Daily |
插入日记条目 insert-diary-entry |
添加特定日期的条目。 Add an entry for a particular day. |
|
im 日记 → 插入每月 i m Diary → Insert Monthly |
插入每月日记条目 insert-monthly-diary-entry |
添加该月中某一天的条目。 Add an entry for the day of the month. |
|
ic 日记 → 插入循环 i c Diary → Insert Cyclic |
插入循环日记条目 insert-cyclic-diary-entry |
添加一个条目以每n天重复一次。 Add an entry to recur every n days. |
|
ia 日记 → 插入周年纪念日 i a Diary → Insert Anniversary |
插入周年纪念日记条目 insert-anniversary-diary-entry |
添加年度条目(年份仅供参考)。 Add an annual entry (the year is included for reference). |
|
ib 日记 → 插入块 i b Diary → Insert Block |
插入块日记条目 insert-block-diary-entry |
添加块条目。 Add a block entry. |
|
米 m |
标记日记条目 mark-diary-entries |
以不同的字体、颜色或旁边带有加号显示日记条目。 Display diary entries in a different typeface, color, or with a plus sign beside them. |
|
d d |
查看日记条目 view-diary-entries |
显示当前日期的日记条目。 Display diary entries for the current date. |
|
s 日记 → 显示全部 s Diary → Show All |
显示所有日记条目 show-all-diary-entries |
显示日记文件。 Display diary file. |
|
M-= M-= |
日历计数天数区域 calendar-count-days-region |
计算某个地区的天数。 Count the number of days in a region. |
|
M 月亮 → 月相 M Moon → Lunar Phases |
日历月相 calendar-phases-of-moon |
显示三个月的月相。 Display phases of the moon for a three-month period. |
|
S S |
日历-日出-日落 calendar-sunrise-sunset |
给定经度和纬度,显示当前日期的日出和日落时间。 Given longitude and latitude, display sunrise and sunset times for the current date. |
|
C-空格或C-@ C-Space or C-@ |
日历设置标记 calendar-set-mark |
按时间而不是水平标记区域。 Mark regions by time rather than horizontally. |
在 Mac OS X 的 shell 模式下,Emacs 会说:“警告:无法访问 tty(错误文件描述符)。因此此 shell 中没有作业控制。 ”图形版本的 Emacs 会出现这种情况,而不是 从 Mac OS X 终端应用程序运行的版本。如果您使用“哪个 shell?”下的说明更改为不同的 shell在本章前面,错误就消失了。
In shell mode on Mac OS X, Emacs says, "Warning: no access to tty (Bad file descriptor). Thus no job control in this shell." This happens with the graphical version of Emacs, not with the version run from the Mac OS X Terminal application. If you change to a different shell using the instructions under "Which shell?" earlier in this chapter, the error goes away.
某些命令在 Mac OS X 上不起作用。 Mac OS X 图形版找不到某些操作系统命令,尤其是通过M-!调用它们时(对于 shell 命令)。更换不同的外壳;请参阅“哪个 shell?”本章前面的详细信息。另一个问题是,某些 Unix 命令默认在 Mac OS X 上不可用。在 Mac 终端应用程序中尝试它们,看看它们是否完全有效,然后再在 shell 模式下尝试它们。要增强 Mac OS X 的 Unix 功能,请使用 Fink ( http://fink.sourceforge.net ) 下载适用于 Mac OS X 的各种 Unix 命令和软件。
Some commands don't work on Mac OS X. The graphical version of Mac OS X fails to find some operating system commands, especially when invoking them through M-! (for shell-command). Change to a different shell; see "Which shell?" earlier in this chapter for details. Another problem is that some Unix commands are not available by default on Mac OS X. Try them in the Mac Terminal application to see if they work at all before trying them in shell mode. To increase Mac OS X's Unix functionality, use Fink (http://fink.sourceforge.net) to download a wide variety of Unix commands and software for Mac OS X.
某些命令在 Windows 上不起作用。本章介绍了许多 Windows 中没有的命令。 Emacs 的 Windows 端口适用于大多数 Dired 功能、日历和日记。要在 Windows 下获得 Unix 命令功能,请安装 Cygwin ( http://cygwin.com )。
Some commands don't work on Windows. This chapter describes many commands that have no Windows equivalent. The Windows port of Emacs works well for most Dired functions, the calendar, and the diary. To get Unix command functionality under Windows, install Cygwin (http://cygwin.com).
无法通过 Windows 在 USB 打印机上进行打印。许多 USB 打印机不支持从命令行打印。这个问题并不是 Emacs 特有的。
Printing does not work from Windows on USB printers. Many USB printers do not support printing from the command line. This problem is not specific to Emacs.
[ 7 ]如果您通常对set-mark命令使用另一个绑定 ,或者您通常拼写该命令,那么您将在日历中标记区域时遇到问题。在日历中,C-Space和C-@运行calendar-set-mark而不是set-mark,因此区域是按时间标记的,而不仅仅是在屏幕上标记。要在日历中正确标记区域(按时间线性排列,而不是简单地跨屏幕),您必须键入C-Space、C-@或Mx calendar-set-mark来设置标记。
[7] If you normally use another binding for the set-mark command or if you typically spell out that command, you'll run into a problem marking regions in the calendar. In the calendar, C-Space and C-@ run calendar-set-mark rather than set-mark, so that regions are marked by time rather than just across the screen. To mark regions correctly in the calendar (linearly by time rather than simply across the screen), you must type C-Space, C-@, or M-x calendar-set-mark to set the mark.
什么是宏?在 Emacs 中,宏是 只是一组可以反复播放的记录击键。宏是避免重复性工作的好方法。例如,假设您要删除表的第三列。通常,您会转到第一行;移至第三列;删除它;然后转到第二行;给出相同的命令集;等等,直到你完成为止,你的手指会磨损,或者你会感到太无聊。 Emacs 允许您在表格的第一行记录用于工作的击键,然后重复“播放这些”直到完成工作。[ 1 ]
What is a macro? In Emacs, a macro is simply a group of recorded keystrokes you can play back over and over again. Macros are a great way to save yourself repetitive work. For example, let's say you want to delete the third column of a table. Normally, you would go to the first line; move over to the third column; delete it; then go to the second line; give the same set of commands; and so on, until you finish, your fingers wear out, or you get too bored. Emacs lets you record the keystrokes you used to work on the first line of the table, and then "play these back" repeatedly until the job is done.[1]
您在 Emacs 中执行的任何命令或操作(从键入文本到编辑再到切换缓冲区)都可以在宏中完成。毫不奇怪,充分使用宏的关键是识别您何时进行重复性工作:感觉到您连续多次按下了或多或少相同的按键序列。一旦您学会识别重复性工作,您就会对何时使用宏有很好的感觉。您需要的下一个技能是,假设您已经认识到“几乎相同”的击键周期,找出如何使该周期完全相同 -也就是说,找出一组击键,如果重复,将做你想做的事。这些技能都不是特别困难。只要稍加练习,您就会一直使用宏。
Any command or action you do within Emacs, from typing text to editing to switching buffers, can be done within a macro. The key to using macros well is, not too surprisingly, recognizing when you're doing repetitive work: sensing that you have pressed more or less the same sequence of keys several times in a row. Once you learn to recognize repetitious work, you have a good feel for when to use macros. The next talent that you'll need is, given that you've recognized a cycle of "almost identical" keystrokes, figuring out how to make that cycle precisely identical—that is, figuring out a set of keystrokes that, if repeated, will do exactly what you want. Neither of these skills is particularly difficult; with a little practice, you'll be using macros all the time.
如果这听起来像是懒人的编程,那么它就是:宏为您提供了一种简单的方法来完成非常复杂的事情,而无需学习 Lisp,也无需学习任何自定义技巧。如果您为其构建宏的任务是您必须经常执行的任务,则可以保存宏并在需要使用它们时加载它们。通过这种方式,您可以构建一组方便的宏,成为您自己的编辑命令。即使您不编写 Lisp,您也不会局限于 Emacs 提供的命令;你可以自己做!
If this sounds like lazy man's programming, it is: macros give you a simple way to do very complicated things without learning Lisp and without learning any customization tricks. If the task you build the macro for is something you have to do frequently, you can save macros and load them when you want to use them. In this way, you can build up a set of convenient macros that become your own editing commands. Even if you don't write Lisp, you're not limited to the commands Emacs gives you; you can make your own!
您使用宏的用途取决于您在 Emacs 中所做的工作类型。我们使用宏来:
What you use macros for will depend on the kind of work you do in Emacs. We've used macros to:
标记文本以进行格式化。
Mark up text for formatting.
将标题从一个缓冲区复制到另一个缓冲区以创建大纲。
Copy headings from one buffer to another to create an outline.
执行查询替换无法完全处理的复杂搜索和替换类型操作。
Perform complex search-and-replace type operations that query-replace can't quite handle.
创建索引条目。
Create index entries.
重新格式化从其他应用程序导入的文件。
Reformat files that were imported from another application.
编辑表格。
Edit tables.
使用单个命令编译、运行并测试程序的输出。
Compile, run, and test the output from a program with a single command.
操作和清理大型数据集。
Manipulate and clean large datasets.
在学习了使用宏所需的几个基本命令后,您将能够想到更多与宏相关的事情。
You'll be able to think of many more things to do with macros after you learn the few basic commands you need to use them.
开始定义一个
宏,按
F3或Cx (。[ 2 ]缩写
Def出现在模式行上,表明您处于宏定义模式。在此模式下,Emacs 会记录您键入的所有击键,无论它们是命令还是文字文本,因此您可以稍后重播它们 要结束宏,请按F4或Cx );当您离开宏定义模式时,Emacs 将停止记录您的击键。如果发生错误或按Cg ,Emacs 还会自动停止记录您的击键。
To start defining a
macro, press
F3 or C-x (.[2] The abbreviation
Def appears on the mode line, showing that you are
in macro definition mode. In this mode, Emacs records all the
keystrokes that you type, whether they are commands or literal text,
so that you can replay them later. To end the macro, press F4 or C-x );
you leave macro definition mode, and Emacs stops recording your
keystrokes. Emacs also stops recording your keystrokes automatically
if an error occurs or if you press C-g.
当您定义宏时,Emacs 会执行 您的击键并记录它们:也就是说,您在宏定义模式下键入的任何内容都将被视为常规命令并执行。当您定义宏时,您正在进行完全正常的编辑。这样您就可以看到宏完全按照您想要的方式执行,并且 如果您发现宏并不完全符合您的要求,则可以取消它(使用Cg )。
While you're defining a macro, Emacs acts on your keystrokes as well as recording them: that is, anything you type while in macro definition mode is treated as a regular command and executed. While you're defining a macro, you're doing completely normal editing. That way you can see that the macro does exactly what you want it to, and you can cancel it (with C-g) if you notice that the macro isn't really quite what you want.
执行你的 宏,按F4或Cx e。然后,Emacs 会准确地重播您的击键。 (您可以看到, F4有两个与宏相关的不同功能:结束宏定义以及定义后执行宏。)
To execute your macro, press F4 or C-x e. Emacs then replays your keystrokes exactly. (You can see that F4 has two different functions relating to macros: to end a macro definition and, after it's defined, to execute the macro.)
该宏被称为“最后一个”键盘宏,此处最后的意思是最新的。只有一个宏是最后一个键盘宏。宏环与终止环非常相似,允许您在 Emacs 会话期间访问多个宏。
This macro is referred to as the "last" keyboard macro, with last here meaning most recent. Only one macro is the last keyboard macro. A macro ring, much like the kill ring, allows you to access a number of macros during an Emacs session.
表 6-1显示了定义和执行宏所需的步骤。该宏采用普通名字姓氏顺序的名称列表,并将其更改为经常需要的姓氏、名字 命名顺序。
Table 6-1 shows the steps required to define and execute a macro. This macro takes a list of names in the ordinary First Name Last Name order and changes it to the frequently needed Last Name, First Name order.
表 6-1。创建名称转置宏的步骤
Table 6-1. Steps for creating name transposition macro
|
击键 Keystrokes |
行动 Action |
|---|---|
|
F3 或 C-x ( F3 or C-x ( |
启动宏; Start the macro; |
|
钙 C-a |
移至当前行的开头。 Move to the beginning of the current line. |
|
MF M-f |
前进一个字。 Move forward a word. |
|
, , |
输入一个逗号。 Type a comma. |
|
公吨 M-t |
调换第一个和最后一个。 Transpose first and last. |
|
中文 C-n |
移至下一行。 Move to the next line. |
|
F4 或 C-x ) F4 or C-x ) |
结束宏定义。 End the macro definition. |
|
使用表 6-1中给出的击键定义宏。 Define the macro using the keystrokes given in Table 6-1. |
|
|
|
在定义宏时,您调换了第一行上的名称,将光标保留在第二行上。 In defining the macro, you transposed the names on the first line, leaving the cursor on the second line. |
现在让我们勇敢地假设宏是有效的;我们将尝试通过在执行宏的命令前面加上M-5来重复它五次。当然,在现实生活中,在做如此大胆的事情之前,你最好先尝试一次。
Now let's be brave and assume the macro works; we'll try repeating it five times by prefacing the command to execute a macro with M-5. Of course, in real life, you'd be better off trying it once before doing anything so bold.
|
M-5 F4或M-5 Cx e型 Type M-5 F4 or M-5 C-x e |
|
|
|
现在我们已经完成了前六行:一行通过定义宏,另外五行通过执行它。 Now we've done the first six lines: one by defining the macro and five more by executing it. |
该宏运行良好,因此我们可以放心地完成缓冲区的其余部分:输入M-100,然后输入 Cx e或F4。当您到达缓冲区末尾时,Emacs 会自动停止,因此即使您重复 宏的次数超过必要的次数。
The macro works well, so we can finish the rest of the buffer with confidence: type M-100, then C-x e or F4. Emacs stops automatically when you reach the end of the buffer, so it doesn't matter if you repeat the macro more times than necessary.
以下是需要记住的几点:
Here are a few points to remember:
完成宏后,不要忘记按F4或Cx ) 。如果您尝试在定义之前执行宏,Emacs 会报错并忘记宏的定义。
Don't forget to press F4 or C-x ) when you've finished the macro. If you try to execute a macro before it has been defined, Emacs complains and forgets the macro's definition.
Cg终止宏,导致 Emacs 忘记其定义。
C-g terminates a macro, causing Emacs to forget its definition.
事实上,任何错误都会自动终止宏。如果 Emacs 向您发出蜂鸣声,您必须重新开始。
Virtually any error automatically terminates a macro. If Emacs beeps at you, you have to start over.
Emacs完全按照您键入的方式执行击键,没有任何智能。避免做出诸如“当然,当我执行宏时我将位于行的开头(或结尾)”之类的假设。
Emacs executes the keystrokes exactly as you type them, with no intelligence whatsoever. Avoid making assumptions like, "Of course I'll be at the beginning (or end) of the line when I execute the macro."
如果您调用宏并且它做了错误的事情,您可以使用 C-_来撤消它。 Emacs 足够聪明,能够意识到“撤消最后一个命令”意味着“撤消整个宏”而不是“撤消宏内的最后一个命令”。但是,如果使用M- n多次重复宏,则C-_仅撤消宏的最后一个实例,而不是所有实例。
If you invoke a macro and it does the wrong thing, you can use C-_ to undo it. Emacs is smart enough to realize that "undo the last command" means "undo the entire macro" rather than "undo the last command within the macro." However, if you repeat a macro multiple times using M- n, C-_ undoes only the last instance of the macro, not all the instances.
[ 1 ]您可以通过将表的第三列标记为矩形来删除它,如第 7 章所述。但请耐心等待我们指出这一点:当您发现自己在做重复性工作时,宏是需要记住的工具。
[1] You could delete the third column of a table by marking it as a rectangle, as described in Chapter 7. But bear with us for the sake of making this point: when you find yourself doing repetitive work, macros are the tool to remember.
很容易学习如何记录和 重复使用您的击键。然而,当你开始时,你会犯一些错误:你创建一个宏,使用它,然后发现它并不完全按照你的想法做。只要稍加小心,就可以轻松地使您的宏更加有用并且不易出错。
It's easy to learn how to record and reuse your keystrokes. However, when you're starting out, you make a few mistakes: you create a macro, use it, and then find out that it doesn't do exactly what you thought. With a little care, it's easy to make your macros more useful and less vulnerable to mistakes.
好的宏适用于所有情况。因此,在宏中,您应该使用绝对命令而不是相对命令。例如,如果您编写一个宏,在光标所在的单词周围放置格式化字符串,那么无论该单词有多长,您都希望该宏能够工作。因此,您可以使用绝对命令,例如Mf(用于向前字)而不是几个Cf来一次向前移动一个字符。同样, Ce和 Ca等命令适合查找行的开头或结尾,而不是向前或向后移动光标。
Good macros work in all situations. Therefore, within a macro, you should use commands that are absolute rather than relative. For example, if you write a macro that puts a formatting string around the word the cursor is on, you want the macro to work no matter how long the word is. Therefore, you would use an absolute command such as M-f (for forward-word) rather than a few C-fs to move forward one character at a time. Similarly, commands such as C-e and C-a are good for finding the beginning or end of a line rather than moving the cursor forward or backward.
通常,宏以搜索命令开始,该命令将您带到文件中希望宏开始的位置。最好键入搜索参数(如Cs
searchstring),而不是使用命令重复上次搜索 ( Cs Cs )。您可能在定义宏和执行宏之间更改了搜索字符串,并且Cs Cs只记住最后一个搜索字符串是什么。
Often, macros start with a search command that brings you to the
place in the file you want the macro to start. It's
a good idea to type the search argument (as in C-s
searchstring)
rather than using the command to repeat the last search (C-s C-s). You may have changed the search
string between the time you define the macro and the time you execute
it, and C-s C-s remembers only what
the last search string was.
添加并非绝对必要的额外命令(通常是Ca和Ce)通常是一个好主意,只是为了确保您在线上正确定位。宏所做的假设越少,它的效果就越好。因此,如果仅当您从行尾开始时一系列命令才能正常工作,请使用Ce启动宏,即使您已经“知道”仅当您位于行尾时才发出命令线。
It is often a good idea to add extra commands (typically C-a and C-e) that aren't strictly necessary, just to make sure that you're positioned correctly on the line. The fewer assumptions that a macro makes, the better it works. So, if a sequence of commands works correctly only if you start at the end of the line, start the macro with C-e, even if you already "know" that you want to give the command only when you're at the end of the line.
最后,当我们背诵规则和注意事项时,这里还有一个:请记住,您可能想要重复执行宏。只要有一点远见,您就能够创建可以毫无问题地在长链中执行的宏。
Finally, while we're reciting rules and cautions, here's one more: keep in mind that you probably want to execute macros repeatedly. With a little foresight, you'll be able to create macros that can be executed in long chains without problems.
一般来说,好的宏由三个部分组成:
In general, good macros have three parts:
他们找到您希望宏开始工作的位置(通常使用搜索)。
They find the place you want the macro to start working (often using search).
他们完成文本上需要完成的工作。
They do the work that needs to be done on the text.
他们准备重复。
They prepare themselves to repeat.
宏如何准备重复?例如,假设您正在编写一个宏来删除表的第三列。删除该列后,宏应将自身定位在下一行的开头(或任何需要的位置),这样您就不必在重新使用光标之前重新定位光标。
How can a macro prepare itself to repeat? For example, assume that you're writing a macro to delete the third column of a table. After deleting the column, the macro should position itself at the beginning of the next line (or wherever it needs to be) so you don't have to reposition the cursor before reusing it.
这是一个稍微复杂的示例。如果您通过搜索启动宏,则必须确保宏的末尾将光标移过您搜索的最后一个位置。如果不这样做,宏将继续在文件中查找相同的位置,并且永远不会继续到您正在搜索的下一个匹配项。作为一般规则,如果您的宏对一行文本进行操作,则它应该以移动到下一行的开头来结束。请记住,您的目标是创建一系列可以连续执行多次而不会中断的击键序列。
Here's a slightly more complex example. If you start a macro with a search, you have to make sure that the end of the macro moves the cursor past the last spot you searched for. If you don't, the macro will keep finding the same place in the file and never go on to the next occurrence of what you're searching for. As a general rule, if your macro operates on a line of text, it should end by moving to the beginning of the next line. Remember that your goal is to create a sequence of keystrokes that can be executed many times in a row, with no interruption.
有时您可能希望在文件中查找对特定主题的所有引用。表 6-2列出了创建宏的步骤,该宏获取缓冲区中包含单词 Emacs 的每个句子并将其复制到另一个缓冲区。如果您尝试使用此宏,则需要在缓冲区中输入一些有关 Emacs 的文本。您还可以通过打开 Emacs NEWS文件(使用Ch n),然后将其写入文件(Cx Cw NEWS)来获取要使用的测试文件。该缓冲区默认处于查看模式;通过输入Mx text-mode Enter更改为文本模式。
Sometimes you may want to find all the references to a particular topic in a file. Table 6-2 lists steps for creating a macro that takes takes every sentence in the buffer that contains the word Emacs and copies it to another buffer. If you try this macro, you'll need to type some text about Emacs into a buffer. You can also get a test file to work with by opening the Emacs NEWS file (using C-h n), then writing it to a file (C-x C-w NEWS). This buffer is in view mode by default; change to text mode by typing M-x text-mode Enter.
表 6-2。创建 Emacs 引用缓冲区的宏步骤
Table 6-2. Steps for macro that creates a buffer of Emacs references
|
击键 Keystrokes |
行动 Action |
|---|---|
|
F3 或 C-x ( F3 or C-x ( |
开始宏定义; Start macro definition; |
|
emacs C-s emacs |
找到 Emacs 这个词。 Find the word Emacs. |
|
进入 Enter |
搜索成功后停止;如果搜索不成功,它会响铃并停止宏。 Stop the search after it is successful; if the search is unsuccessful, it rings the bell and stops the macro. |
|
嘛 M-a |
移动到句子的开头。[ 3 ] Move to the beginning of the sentence.[3] |
|
C-空间 C-Space |
设置标记。 Set the mark. |
|
我 M-e |
移至句子末尾。 Move to the end of the sentence. |
|
分子量 M-w |
将这句话复制到杀戮环中。 Copy the sentence to the kill ring. |
|
Cx b emacsrefs 输入 C-x b emacsrefs Enter |
移动到一个名为 的缓冲区 Move to a buffer called |
|
CY C-y |
插入句子。 Insert the sentence. |
|
进入 Enter |
下一个句子另起一行。 Start the next sentence on a new line. |
|
Cx b 输入 C-x b Enter |
移回原始缓冲区。 Move back to the original buffer. |
|
F4 或 C-x ) F4 or C-x ) |
结束宏定义; End the macro definition; |
[ 3 ] 马云对“句子”的定义是由变量sentence-end控制的,这是一个相当复杂的正则表达式。默认情况下,句子以句号、问号或感叹号结尾,可选地后跟引号或圆括号(包括方括号或大括号),后跟两个或多个空格或换行符。 [3] M-a's definition of a "sentence" is controlled by the variable sentence-end, which is a fairly complex regular expression. By default, a sentence ends with a period, question mark, or exclamation mark, optionally followed by a quotation mark or parenthesis (including brackets or braces), and followed by two or more spaces or a newline. | |
现在,假设您已经构建了表 6-2中概述的宏,并且可以使用F4调用它。以下屏幕显示了运行五次然后显示缓冲区时发生的情况emacsrefs。
Now, assume that you've already constructed the
macro outlined in Table 6-2 and that you can
invoke it with F4. The following
screen shows what happens when you run it five times and then display
the emacsrefs buffer.
|
类型:M-5 F4或M-5 Cx e,后跟 Cx b Enter Type: M-5 F4 or M-5 C-x e, followed by C-x b Enter |
|
|
|
通过重复执行宏,我们创建了一个包含对 Emacs 编辑器的引用的缓冲区。 By executing the macro repeatedly, we've created a buffer that contains references to the Emacs editor. |
与前面的示例一样,您可以在定义宏时在无限数量的缓冲区之间来回跳转。宏不需要局限于一个缓冲区。使用多个缓冲区的宏更难以调试;当涉及多个缓冲区时,您将很难跟踪光标和标记的位置。对于您正在访问的缓冲区也很容易做出错误的假设;因此,最好明确指定缓冲区名称。然而,当您习惯使用宏和多个缓冲区后,您会惊讶地发现您几乎不费吹灰之力就能完成如此多的工作。
As in the previous example, you can jump back and forth between an unlimited number of buffers while defining a macro. Macros don't need to be confined to one buffer. Macros that work with several buffers are more difficult to debug; when several buffers are involved, it becomes harder for you to keep track of where the cursor and the mark are. It is also easy to make mistaken assumptions about what buffer you're visiting; hence, it's a good idea to specify the buffer name explicitly. However, after you get accustomed to working with macros and multiple buffers, you'll be amazed at how much work you can do with almost no effort.
Windows 有时在宏中很有用,但是,您必须再次小心。最好在屏幕上启动一个带有一个窗口的宏,让该宏打开其他窗口,最后关闭除一个窗口之外的所有窗口 ( Cx 1 )。如果您编写一个在屏幕上有两个窗口的宏,然后尝试在屏幕上有四个窗口执行它,那么结果充其量也将是不可预测的!一般来说,移动到指定的缓冲区Cx b比使用
Cx o移动到“其他”窗口(太模糊而通常没有用)buffername更好
。另一个窗口可以是任何东西——
缓冲区、
缓冲区、缓冲区等等。移动到命名缓冲区总是能让您到达正确的位置,无论缓冲区如何(或是否)显示。*Help**Completion**shell*
Windows are sometimes useful in macros, but, again, you have to watch
out. It's better to start a macro with one window on
the screen, have the macro open other windows, and finally close all
but one window (C-x 1). If you write
a macro with two windows on the screen and later try to execute it
with four windows on the screen, the results will be unpredictable at
best! In general, moving to a named buffer, C-x
b
buffername, is preferable to
moving to the "other" window using
C-x o (too vague to be generally
useful). The other window could be anything—a
*Help* buffer, *Completion*
buffer, *shell* buffer, and so on. Moving to a
named buffer always gets you to the right place, no matter how (or
whether) the buffer is displayed.
您可以编辑宏并 通过几种不同的方式对其进行更改。对于此示例,我们选择了通用编辑命令edit-kbd-macro,它绑定到Cx Ck e。有几个宏编辑命令可用,但这个命令适用于所有类型的宏,因此值得学习。
You can edit a macro and make changes to it in a few different ways. For this example, we chose an all-purpose editing command, edit-kbd-macro, which is bound to C-x C-k e. Several macro editing commands are available, but this one works for all types of macros, so it's good to learn.
我们的宏可以进行一些调整。首先,在我们的 Emacs NEWS文件副本中找到对 Emacs 的引用是相当蹩脚的。也许我们对在 Emacs 中更频繁地使用鼠标感兴趣,并且想了解界面这一部分的更改。我们将编辑宏来搜索单词mouse。我们还将对其进行修改,以便它标记一个段落而不是一个句子,因为句子并不能真正提供足够的上下文来提供帮助。
Our macro could use a bit of tweaking. First of all, finding references to Emacs in our copy of the Emacs NEWS file is pretty lame. Perhaps we're interested in using a mouse more frequently with Emacs and would like to know about changes to that part of the interface. We'll edit the macro to search for the word mouse. We'll also modify it so it marks a paragraph rather than a sentence since a sentence doesn't really provide enough context to be helpful.
让我们开始编辑宏。
Let's start editing the macro.
Emacs 询问您是否要编辑最后一个键盘宏 ( Cx e )、命名宏 ( Mx )、作为宏的最后 100 个击键(称为“丢失”( Ch l ))或按键(表示您绑定的击键)宏到)。是的,有很多选择,在本章后面,我们将描述命名宏以及将宏绑定到键(您可以自己尝试通过丢失创建宏)。现在,只需选择Cx e 编辑最后一个键盘宏。
Emacs asks you if you want to edit the last keyboard macro (C-x e), a named macro (M-x), the last 100 keystrokes as a macro, termed "lossage" (C-h l), or keys (meaning the keystrokes you bound a macro to). Yes, that's a lot of choices, and later in the chapter we describe named macros and binding macros to keys (you can experiment on your own with creating a macro from lossage). For now, just choose C-x e to edit the last keyboard macro.
请注意该缓冲区顶部附近的两个字段::
Command和Key:。现在,
Command: 说last-kbd-macro。如果这是一个命名宏,则该命令将是您为宏指定的名称。此外,为了频繁使用,您可以将宏绑定到一个键,此时Key: 字段列出了执行该宏的击键。现在它说是
none因为我们还没有定义任何击键。
Notice two fields near the top of this buffer,
Command: and Key:. Right now,
Command: says last-kbd-macro.
If this were a named macro, the command would be the name you gave
your macro. Additionally, for frequent use, you can bind your macro
to a key, at which point the Key: field lists the
keystrokes to execute this macro. Right now it says
none because we haven't defined
any keystrokes yet.
请注意,Emacs 在整个宏中插入注释。它试图将击键映射到命令。如果您向宏添加命令,则无需更新这些注释或添加注释; Emacs 自己做这件事。
Note that Emacs inserts comments all through the macro. It's attempting to map keystrokes to commands. You do not need to update these comments or add comments if you add commands to your macro; Emacs does that itself.
为了调整我们的宏,我们将第二行的搜索字符串从emacs更改为mouse。请注意,我们只需按Ck即可擦除线条并键入鼠标。现在将Ma更改为M-{
并将Me更改为M-}。我们将缓冲区名称从 更改
emacsrefs为mouseinfo。
To tweak our macro, we change the search string on the second line
from emacs to mouse. Note
that we can just press C-k to wipe
out the line and type mouse. Now change M-a to M-{
and M-e to M-}. We change the buffer name from
emacsrefs to mouseinfo.
|
我们对上一段进行了编辑。屏幕看起来像这样: We've made the edits from the previous paragraph. The screen looks like this: |
|
|
|
一个修改后的宏,用于捕获有关在 Emacs 中使用鼠标的信息。 A modified macro that captures information about using a mouse in Emacs. |
要退出宏编辑缓冲区,我们必须输入Cc Cc并返回到
NEWS缓冲区。让我们这样做,然后再次执行该宏,看看会发生什么。
To exit the macro editing buffer, we have to type C-c C-c and go back to our
NEWS buffer. Let's do that and
then execute the macro again to see what happens.
虽然我们最新的宏是有趣的是,它并不是真正的通用宏。这是一次性问题的临时解决方案。它可以为您节省一些工作,但不够通用,无法保存并再次使用。另一方面,我们用于转置名称的宏通常很有用。我们想再次使用它。我们想将它绑定到一个键上。但它不再是“最新”的键盘宏。
Although our latest macro is interesting, it's not really a general purpose macro. It is a temporary solution to a one-time problem. It saves you some work, but it isn't general enough to save and use again. On the other hand, our macro to transpose names is generally useful. We'd like to use it again. We'd like to bind it to a key. But it is no longer the "latest" keyboard macro.
正如我们之前提到的,Emacs 有一个宏环,很像臭名昭著的kill环。它在我们刚刚描述的情况下很有用,但由于宏定义过程的脆弱性,它也很有用。您创建了一个宏并做出了错误的举动,敲响了警钟,并且您的宏被取消。创建一个不执行任何操作的宏相当容易。也许您刚刚创建的宏很棒,而这个新的非功能性无宏已经取代了它。再次强调,宏环是解决方案。要从环中删除宏,请键入Cx Ck Cd(对于 kmacro-delete-ring-head)。这将删除最近定义的键盘宏。
As we mentioned earlier, Emacs has a macro ring much like the infamous kill ring. It's useful in the case we've just described, but it's also useful because of the fragility of the macro definition process. You create a macro and make a wrong move that rings the bell, and your macro is canceled. It's fairly easy to create a macro that does nothing. Perhaps the macro that you just created was wonderful, and this new nonfunctional nothing macro has supplanted it. Again, the macro ring is the solution. To delete a macro from the ring, type C-x C-k C-d (for kmacro-delete-ring-head). This deletes the most recently defined keyboard macro.
如果你想交换两个宏的位置怎么办?相反,请键入 Cx Ck Ct(对于kmacro-swap-ring)。这会转置宏 1 和 2。
What if you want to swap the positions of two macros? Instead, type C-x C-k C-t (for kmacro-swap-ring). This transposes macros 1 and 2.
从更一般的意义上来说,您可以通过键入Cc Ck Cp(对于 kmacro-cycle-ring-previous)循环到先前定义的宏。要将环以其他方式移动,请键入Cx Ck Cn (对于kmacro-cycle-ring-next)。熟悉的 用于上一个绑定的Cp和用于下一个绑定的Cn附加到通用宏键盘前缀Cx Ck上。
In a more general sense, you can cycle to the previously defined macro by typing C-c C-k C-p (for kmacro-cycle-ring-previous). To move the ring the other way, type C-x C-k C-n (for kmacro-cycle-ring-next). The familiar C-p for previous and C-n for next bindings are appended to the general macro keyboard prefix C-x C-k.
在使用转置名称宏之前,我们必须再次定义它,或者,如果您已经完成了我们的示例,请键入Cx Ck Cp以移至上一个宏。
Before we can work with the transpose names macro, we must either define it again or, if you've been working through our examples, type C-x C-k C-p to move to the previous macro.
将宏绑定到按键 简单。键序列Cx Ck 0到9和大写字母A到Z 保留用于用户宏绑定。您可以选择一个让您印象深刻的宏助记符。
Binding a macro to a key is easy. The key sequences C-x C-k 0 through 9 and capital A through Z are reserved for user macro bindings. You can choose one that strikes you as mnemonic for your macro.
例如,要将转置名称宏绑定到Cx Ck T,请输入Cx Ck b。 Emacs 提示输入键绑定。键入Cx Ck T Enter。 Emacs 确认,
Keyboard macro bound to C-x C-k T.以这种方式将宏命令绑定到按键仅适用于一个会话。我们想保留这个宏,所以请继续阅读以了解如何使此绑定永久化。
For example, to bind our transpose names macro to C-x C-k T, type C-x C-k
b. Emacs prompts for the key binding. Type C-x C-k T Enter. Emacs confirms,
Keyboard macro bound to C-x C-k T. Binding a macro
command to a key in this way works for only one session. We want to
keep this macro, so read on to find out how to make this binding
permanent.
在本节中,我们将描述 如何保存宏以便您可以在不同的编辑会话中使用它们。要保存宏、将其永久绑定到键并在后续 Emacs 会话中加载它,请执行以下步骤:
In this section, we'll describe how to save macros so that you can use them in different editing sessions. To save a macro, bind it permanently to a key, and load it in subsequent Emacs sessions, follow these steps:
定义宏(如果尚未定义)。
Define the macro, if you haven't already.
键入Cx Ck n(对于name-last-kbd-macro)。现在为宏输入一个名称,然后按Enter。听起来像非 Emacs 的名称是最好的,这样 Emacs 就不会将其与它自己的命令之一混淆。执行此命令后,Emacs 会记住该宏以用于其余的编辑会话。要再次使用它,请键入命令Mx name(其中name 是您选择的名称)。 Emacs 将您的命名宏视为它自己的命令之一;如果您在输入姓名的几个字母后按Tab键,它会显示在完成列表中。
Type C-x C-k n (for name-last-kbd-macro). Now type a name for your macro and press Enter. A non-Emacs sounding name is best so that Emacs doesn't confuse it with one of its own commands. Once you've executed this command, Emacs remembers the macro for the rest of the editing session. To use it again, type the command M-x name (where name is the name you've chosen). Emacs treats your named macro like one of its own commands; it shows up in completion lists if you press Tab after typing a few letters of the name.
如果要永久保存宏定义,则必须将宏定义插入到文件中。这可能是您的 .emacs文件或通过.emacs文件加载的宏文件。键入Cx Cf filename Enter查找要插入定义的文件,并通过键入M->移动到该文件的末尾。
If you want to save the macro definition permanently, you must insert the macro definition into a file. This could be your .emacs file or a macro file that you load through your .emacs file. Type C-x C-f filename Enter to find the file into which to insert the definition and move to the end of it by typing M->.
键入Mx insert-kbd-macro 输入 宏名称 Enter。 Emacs 插入代表您的宏的 Lisp 代码。
Type M-x insert-kbd-macro Enter macroname Enter. Emacs inserts Lisp code that represents your macro.
向.emacs添加一行以使键绑定永久化。例如,如果我们调用宏transpose-names并将其绑定到Cx Ck T,我们会将此行添加到我们的 .emacs文件(或其他宏定义文件)中:
(全局设置键“\Cx\C-kT”'转置名称)
Add a line to .emacs make the key binding permanent. For example, if we called our macro transpose-names and bound it to C-x C-k T, we would add this line to our .emacs file (or other macro definition file):
(global-set-key "\C-x\C-kT" 'transpose-names)
如果您将宏保存在其他文件中,则不会自动加载它。例如,假设您定义了一个名为transpose-names的宏,并将其放置在 ~/macros目录中的 文件html.macs中。将此行添加到您的 .emacs文件中以自动加载宏:
(加载文件“~/macros/html.macs”)
If you save the macro in some other file, it won't be loaded automatically. For example, let's say that you have defined a macro called transpose-names and placed it in the file html.macs, in the directory ~/macros. Add this line to your .emacs file to load your macros automatically:
(load-file "~/macros/html.macs")
保存.emacs文件,如果不同,则保存插入宏的文件。退出并重新启动 Emacs。现在,您可以通过键入Mx transpose-names Enter或按Cx Ck T来执行此宏。
Save the .emacs file and, if different, the file in which you inserted your macro. Exit and restart Emacs. You can now execute this macro either by typing M-x transpose-names Enter or by pressing C-x C-k T.
到目前为止,我们已经介绍了编写、执行和保存键盘宏的基础知识。现在让我们讨论 Emacs 允许您添加到宏中的一些更高级的功能:暂停宏以进行键盘输入以及在宏中插入查询。
So far, we've covered the basics of writing, executing, and saving keyboard macros. Now let's discuss a couple of more advanced features Emacs lets you add to your macros: pausing a macro for keyboard input and inserting a query in a macro.
有时是 短暂暂停宏以便您可以输入内容很有用。例如,如果您写了很多信件,则可以使用一个宏来打印出模板,然后暂停以供您填写变量(例如日期和收件人姓名)。您可以通过将递归编辑插入宏来执行此任务(以及类似的任务)。递归编辑只是一种奇特的方式来表达:“停下来,让我输入一会儿,然后从我上次停下来的地方继续执行宏。”
Sometimes it's useful to pause a macro briefly so you can type something. For example, if you write a lot of letters, you could have a macro that prints out a template and then pauses for you to fill in variables (such as the date and the recipient's name). You can perform this task (and similar tasks) by inserting a recursive edit into a macro. A recursive edit is just a fancy way to say, "Stop and let me type a while, then pick up the macro where I left off."
定义宏时,请在要进行递归编辑的位置键入Cu Cx q 。 Emacs 进入递归编辑。 (您可以看出您正在进行递归编辑,因为方括号出现在模式行上;您将在本节后面的屏幕截图中看到它们。)您在递归编辑期间键入的任何内容都不会成为宏的一部分。您可以输入任何您想要的内容,然后按CMc退出递归编辑。请注意,当您键入CMc时,方括号如何消失。当方括号不再出现在屏幕上时,您就已经离开了递归编辑。此时您输入的任何内容都将成为宏的一部分。您可以根据需要在宏中添加任意数量的暂停。
When you're defining a macro, type C-u C-x q at the point where you want the recursive edit to occur. Emacs enters a recursive edit. (You can tell you're in a recursive edit because square brackets appear on the mode line; you'll see them in the screenshots later in this section.) Nothing you type during the recursive edit becomes a part of the macro. You can type whatever you want to and then press C-M-c to exit the recursive edit. Notice how the square brackets disappear when you type C-M-c. When the square brackets are no longer on the screen, you have left the recursive edit. Anything you type at this point becomes part of the macro. You can put as many pauses in your macros as you want to.
下面是一个宏示例,它将商业信函模板放在屏幕上,并使用递归编辑来让您键入寄信人地址、收件人的姓名和地址以及日期。因为模式行上的括号是您要输入的内容的非常微妙的线索,所以我们将向该宏的用户提供有关输入内容的明确指示。表 6-3 提供了这些说明。
Here's an example of a macro that puts a business letter template on the screen and uses recursive edits to let you type your return address, the recipient's name and address, and the date. Because the brackets on the mode line are a pretty subtle clue to what you are going to type, we'll give the user of this macro explicit instructions about what to type. Table 6-3 provides these instructions.
表 6-3。创建商业信函宏的步骤
Table 6-3. Steps for creating a business letter macro
|
击键 Keystrokes |
行动 Action |
|---|---|
|
F3 或 C-x ( F3 or C-x ( |
启动键盘宏定义。 Start keyboard macro definition. |
|
M-5进入 M-5 Enter |
输入5个空行。 Put in 5 blank lines. |
|
输入您的地址并按 CMc Type your address and press C-M-c |
显示 Display |
|
钙 C-a |
移至行首。 Move to the beginning of the line. |
|
铜Cxq C-u C-x q |
输入递归编辑,在此期间您键入的击键不会记录为宏的一部分。 Enter a recursive edit, during which the keystrokes you type are not recorded as part of the macro. |
|
CMc C-M-c |
退出递归编辑。 Exit the recursive edit. |
|
铈 C-e |
移动到该行的末尾。 Move to the end of the line. |
|
M-5进入 M-5 Enter |
将光标向下移动 5 行。 Move the cursor down 5 lines. |
|
输入收件人姓名和地址,然后按 CMc Type recipient name and address and press C-M-c |
显示 Display |
|
钙 C-a |
移至行首。 Move to the beginning of the line. |
|
铜Cxq C-u C-x q |
输入递归编辑。 Enter a recursive edit. |
|
CMc C-M-c |
退出递归编辑。 Exit the recursive edit. |
|
铈 C-e |
移动到该行的末尾。 Move to the end of the line. |
|
M-5进入 M-5 Enter |
将光标向下移动 5 行。 Move the cursor down 5 lines. |
|
输入日期并按 CMc Type date and press C-M-c |
显示 Display |
|
钙 C-a |
移至行首 Move to the beginning of the line |
|
铜Cxq C-u C-x q |
输入递归编辑。 Enter a recursive edit. |
|
CMc C-M-c |
退出递归编辑。 Exit the recursive edit. |
|
铈 C-e |
移动到该行的末尾。 Move to the end of the line. |
|
M-5进入 M-5 Enter |
将光标向下移动 5 行。 Move the cursor down 5 lines. |
|
亲爱的空间 Dear Space |
屏幕上显示亲爱的。 Display Dear on the screen. |
|
F4 或 C-x ) F4 or C-x ) |
结束键盘宏定义。 End keyboard macro definition. |
以下屏幕显示表 6-3中定义的宏在运行时的样子。
The following screens show what the macro defined in Table 6-3 looks like when you run it.
|
输入您的地址并按:CMc Type your address and press: C-M-c |
|
|
|
宏会暂停,以便您可以键入收件人的姓名和地址。 The macro pauses so you can type the recipient's name and address. |
|
输入收件人的姓名和地址,然后按: CMc Type the recipient's name and address and press: C-M-c |
|
|
|
宏暂停,以便您可以键入日期。 The macro pauses so you can type the date. |
|
输入日期并按:CMc Type the date and press: C-M-c |
|
|
|
宏通过键入字母的开头来结束。 The macro finishes by typing the opening for the letter. |
现在宏已经完成编辑;您可以输入收件人的姓名,然后输入信件正文,当然您可以返回并编辑已填写的任何信息。
Now the macro has finished editing; you can type the recipient's name and then the body of the letter, and of course you can go back and edit any of the information you've already filled in.
您的任务越复杂 宏执行得越好,使宏足够通用以在每种情况下工作就越困难。尽管宏可以做很多事情,但它们不是程序:不能有if 语句、循环以及与程序关联的其他内容。特别是,宏无法从用户获取输入,然后根据该输入执行某些操作。
The more complex the task your macro performs, the more difficult it is to make the macro general enough to work in every case. Although macros can do a lot of things, they aren't programs: you can't have if statements, loops, and the other things you associate with a program. In particular, a macro can't get input from the user and then take some action on the basis of that input.
然而,有一个功能可以让宏以有限的方式从用户那里获取输入。您可以创建一个在运行时查询用户的宏;它的工作原理很像查询替换。要创建此类宏,请在到达宏定义中希望宏查询用户的位置时键入Cx q 。没有什么是立即发生的;继续像平常一样定义宏。
However, one feature lets a macro get input, in a limited way, from the user. You can create a macro that queries the user while it is running; it works much like a query-replace. To create this kind of a macro, type C-x q when you reach the point in the macro definition where you want the macro to query the user. Nothing happens immediately; go on defining the macro as you normally would.
当您执行宏时,事情会变得有趣。当到达宏中您键入Cx q 的位置时,Emacs 会在迷你缓冲区中打印一条查询:
Things get interesting later, when you execute the macro. When it gets to the point in the macro where you typed C-x q, Emacs prints a query in the minibuffer:
继续宏吗? (y、n、RET、Cl、Cr)
Proceed with macro? (y, n, RET, C-l, C-r)
这里列出的响应与查询替换中的响应类似:
The responses listed here are analogous to those in query-replace:
按y表示继续并继续进行下一次重复(如果有)。
Pressing y means to continue and go on to the next repetition, if any.
按n意味着停止执行宏,但继续执行下一个重复(如果有)。
Pressing n means to stop executing the macro but go on to the next repetition, if any.
按Enter意味着停止执行宏并取消任何重复。
Pressing Enter means to stop executing the macro and cancel any repetitions.
按Cr启动递归编辑,您可以进行任何编辑或移动您可能想要的内容,然后在退出递归编辑时恢复宏。要退出递归编辑,请按CMc。 Emacs 再次询问您是否要继续执行宏,您输入 y表示是,输入n或Enter 表示否。
Pressing C-r starts a recursive edit, which lets you do any editing or moving around you may want to and then resume the macro when you exit the recursive edit. To exit a recursive edit, press C-M-c. Emacs again asks if you want to proceed with the macro, and you type y for yes or n or Enter for no.
按Cl将光标所在的行置于屏幕中间(这有利于了解上下文)。与Cr类似,Emacs 再次询问您是否要继续执行宏,您必须回答y、n或 Enter。
Pressing C-l puts the line the cursor is on in the middle of the screen (this is good for getting a feel for the context). Similar to C-r, Emacs again asks if you want to proceed with the macro, and you have to answer y, n, or Enter.
按Cg(尽管未列为选项)可取消查询和宏;它类似于按 Enter。
Pressing C-g (although not listed as an option) cancels the query and the macro; it is similar to pressing Enter.
假设您编写了一个宏,将注释从程序复制到另一个缓冲区。我们程序中的注释前面有一个斜杠,因此您可以通过搜索斜杠来启动宏。然而,并非所有评论都值得复制。通过查询进行搜索后,您可以根据具体情况决定搜索是否找到了您想要复制的评论。表 6-4显示了将注释复制到另一个缓冲区的宏。
Let's say that you write a macro that copies comments from a program to another buffer. The comments in our program are preceded by a slash, so you start the macro with a search for a slash. However, not all comments are worth copying. Following the search with a query lets you decide case by case whether the search has found a comment you want to copy. Table 6-4 shows a macro to copy comments to another buffer.
表 6-4。带查询的注释复制宏
Table 6-4. Comment-copying macro with a query
|
击键 Keystrokes |
行动 Action |
|---|---|
|
F3 F3 |
开始宏定义。 Start the macro definition. |
|
CS / C-s / |
搜索斜杠。 Search for a slash. |
|
进入 Enter |
搜索成功后停止搜索。 Stop the search when it is successful. |
|
C-x q |
在宏中插入查询;当您运行宏时,Emacs 会询问您是否要继续。 Insert a query in the macro; Emacs asks you if you want to proceed at this point when you run the macro. |
|
MF M-f |
前进一个字。 Move forward one word. |
|
MB M-b |
移至该单词的开头。 Move to the beginning of this word. |
|
C-空间 C-Space |
设置标记。 Set the mark. |
|
铈 C-e |
移动到该行的末尾。 Move to the end of the line. |
|
CF C-f |
向前移动一个字符。 Move forward one character. |
|
分子量 M-w |
将评论复制到 Kill Ring 中。 Copy the comment to the kill ring. |
|
CX b 评论 C-x b comments |
移动到一个名为 的缓冲区 Move to a buffer called |
|
CY C-y |
将注释插入缓冲区。 Insert the comment in the buffer. |
|
CXB C-x b |
移回原始缓冲区。 Move back to the original buffer. |
|
F4 F4 |
结束宏定义。 End the macro definition. |
特殊命令 允许您在区域中的每一行上执行宏。您是否经常遇到一封电子邮件,其中包含您想要提取的文本,但该电子邮件引用了多个缩进级别?当然,我们可以想出多种方法来快速删除缩进,但面向行的宏也是一种快速方法。您可以定义宏并通过键入Cx Ck r(适用于apply-macro-to-region-lines)在区域上执行它。还记得之前我们说过宏应该将自己设置为重复吗?该命令有所不同,因为它希望一次只处理一行。您不想通过移动到下一行来将其设置为重复;它会自动执行此操作。
A special command lets you execute a macro on each line in a region. How frequently do you encounter an email with text that you want to yank, but that is quoted several indentation levels? Of course, we can think of several ways to delete the indentation quickly, but a line-oriented macro is a quick approach too. You define the macro and execute it on a region by typing C-x C-k r (for apply-macro-to-region-lines). Remember that earlier we said that macros should set themselves up to repeat? This command is different because it expects to work on one line at a time. You don't want to set it up to repeat by moving to the next line; it does that automatically.
表 6-5显示了一个快速的面向行的宏,它可以删除电子邮件或电子邮件中引用的文本中的缩进标记。 新闻组消息。
Table 6-5 shows a quick line-oriented macro that deletes indentation marks from text quoted in an email or newsgroup message.
表 6-5。删除缩进标记的宏
Table 6-5. Macro for deleting indentation marks
|
击键 Keystrokes |
行动 Action |
|---|---|
|
F3 F3 |
开始宏定义。 Start the macro definition. |
|
钙 C-a |
移至行首。 Move to the beginning of the line. |
|
MF M-f |
前进一个字。 Move forward one word. |
|
MB M-b |
移至该单词的开头。 Move to the beginning of this word. |
|
C-空间 C-Space |
设置标记。 Set the mark. |
|
钙 C-a |
移至行首。 Move to the beginning of the line. |
|
连续波 C-w |
删除无关的缩进字符。 Delete the extraneous indentation characters. |
|
F4 F4 |
结束宏定义。 End the macro definition. |
宏是简化重复编辑的重要工具。它们让您可以编写自己的命令来执行复杂的任务,而无需了解您已经知道的任何内容:用于移动和操作文本的基本 Emacs 命令。即使您是 Emacs 新手,您也应该能够轻松使用宏。
Macros are an important tool for streamlining repetitive editing. They let you write your own commands for performing complex tasks without needing to know anything more than you already know: the basic Emacs commands for moving around and manipulating text. Even if you're an Emacs novice, you should be able to use macros with little difficulty.
然而,Emacs 几乎是无限灵活的,宏并不能包揽一切。在许多情况下,没有什么可以替代编写一个完全符合您要求的 Lisp 函数。如果您了解 Lisp 或想学习一些,您可以编写自己的 Lisp 函数来完成键盘宏无法处理的更复杂的任务。第 11 章介绍了编写 Lisp 函数的基础知识。
However, Emacs is almost infinitely flexible, and macros cannot do everything. In many situations, there's no substitute for writing a Lisp function that does exactly what you want. If you know Lisp or would like to learn some, you can write your own Lisp functions to do more complex tasks than keyboard macros can handle. Chapter 11 covers the basics of writing Lisp functions.
表 6-6总结 宏命令。
Table 6-6 summarizes macro commands.
表 6-6。宏命令
Table 6-6. Macro commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CX ( C-x ( |
kmacro-开始宏 kmacro-start-macro |
开始宏定义。 Start macro definition. |
|
F3 F3 |
kmacro-启动宏-或插入-计数器 kmacro-start-macro-or-insert-counter |
开始宏定义。如果在定义宏时按下,则插入一个计数器。 Start macro definition. If pressed while defining a macro, insert a counter. |
|
CX) C-x ) |
kmacro 结束宏 kmacro-end-macro |
结束宏定义。 End macro definition. |
|
F4 F4 |
kmacro 结束或调用宏 kmacro-end-or-call-macro |
结束宏定义(如果定义正在进行中)或调用最后一个键盘宏。 End macro definition (if definition is in progress) or invoke last keyboard macro. |
|
CXe C-x e |
kmacro 结束和调用宏 kmacro-end-and-call-macro |
执行最后定义的键盘宏。可以输入e来重复宏。 Execute last keyboard macro defined. Can type e to repeat macro. |
|
CXCn C-x C-k n |
名称姓氏 kbd 宏 name-last-kbd-macro |
命名您最后创建的宏(保存之前)。 Name the last macro you created (before saving it). |
|
(没有任何) (none) |
插入 kbd 宏 insert-kbd-macro |
将您命名的宏插入文件中。 Insert the macro you named into a file. |
|
(没有任何) (none) |
宏名 macroname |
执行命名的键盘宏。 Execute a named keyboard macro. |
|
C-x q |
kbd 宏查询 kbd-macro-query |
在宏定义中插入查询。 Insert a query in a macro definition. |
|
铜Cxq C-u C-x q |
(没有任何) (none) |
在宏定义中插入递归编辑。 Insert a recursive edit in a macro definition. |
|
CMc C-M-c |
退出递归编辑 exit-recursive-edit |
退出递归编辑。 Exit a recursive edit. |
|
CXCb C-x C-k b |
kmacro 绑定到键 kmacro-bind-to-key |
将宏绑定到按键(Cx Ck 0 - 9 和A - Z保留用于宏绑定)。仅持续当前会话。 Bind a macro to a key (C-x C-k 0-9 and A-Z are reserved for macro bindings). Lasts for current session only. |
|
Cx Ck 空间 C-x C-k Space |
kmacro-步骤-编辑宏 kmacro-step-edit-macro |
在单步执行宏的同时编辑宏(我们认为该界面过于复杂)。 Edit a macro while stepping through it (in our opinion, the interface is overly complex). |
|
CXCl C-x C-k l |
kmacro-编辑-丢失 kmacro-edit-lossage |
将最后 100 个击键变成键盘宏。如果最近 100 次击键中有任何鼠标点击,则不起作用。 Turn the last 100 keystrokes into a keyboard macro. If any mouse clicks are among the last 100 keystrokes, does not work. |
|
CXCe C-x C-k e |
编辑 kbd 宏 edit-kbd-macro |
通过键入 Cx e(代表最后定义的键盘宏)、Mx(代表命名宏)、Ch l(代表丢失)或击键(代表绑定到某个键的宏)来编辑键盘宏。 Edit a keyboard macro by typing C-x e for the last keyboard macro defined, M-x for a named macro, C-h l for lossage, or keystrokes for a macro bound to a key. |
|
Cx Ck 输入 C-x C-k Enter |
kmacro-编辑宏 kmacro-edit-macro |
编辑最后一个键盘宏。 Edit the last keyboard macro. |
|
CXCCKCE C-x C-k C-e |
kmacro-编辑宏-重复 kmacro-edit-macro-repeat |
再次编辑最后一个键盘宏。 Edit the last keyboard macro again. |
|
Cx Ck Ct C-x C-k C-t |
km宏交换环 kmacro-swap-ring |
将最后一个键盘宏与前一个键盘宏调换。 Transpose last keyboard macro with previous keyboard macro. |
|
Cx Ck 镉 C-x C-k C-d |
kmro-删除环头 kmacro-delete-ring-head |
从宏环中删除最后一个键盘宏。 Delete last keyboard macro from the macro ring. |
|
Cx Ck Cp C-x C-k C-p |
kmacro-cycle-ring-前一个 kmacro-cycle-ring-previous |
移至宏环中的上一个宏。 Move to the previous macro in the macro ring. |
|
Cx Ck Cn C-x C-k C-n |
kmro-cycle-ring-next 宏循环环下一个 kmacro-cycle-ring-next |
移至宏环中的下一个宏。 Move to the next macro in the macro ring. |
|
CXCr C-x C-k r |
将宏应用于区域线 apply-macro-to-region-lines |
将此宏应用于区域中的每一行。 Apply this macro to each line in a region. |
Emacs 本质上是一个文本编辑器,而不是文字处理程序:它是一个创建包含您在屏幕上看到的内容的文件的工具,而不是一个使文本文件在打印时看起来很漂亮的工具。但是,Emacs 确实使您能够执行以下操作:
Emacs is fundamentally a text editor, rather than a word processor: it is a tool that creates files containing exactly what you see on the screen rather than a tool that makes text files look beautiful when printed. However, Emacs does give you the capability to do the following:
使用制表符和其他缩进技巧来缩进文本。
Indent text using tabs and other indentation tricks.
文本的中心词、行和段落。
Center words, lines, and paragraphs of text.
使用大纲模式隐藏和显示文档的部分内容,让您了解文档的整体结构。大纲模式可以更轻松地从粗略轮廓到详细轮廓,再到草稿,再到最终产品。
Hide and show portions of a document using outline mode, which gives you a feel for a document's overall structure. Outline mode can make it easier to go from rough outline, to detailed outline, to rough draft, to the final product.
按列而不是按行编辑(在创建或更改表或使用面向列的数据集时特别有用),在 Emacs 中称为矩形 编辑。
Edit by column rather than by line (especially helpful when you create or change tables or work with column-oriented datasets), referred to in Emacs as rectangle editing.
使用键盘字符或鼠标创建简单的图片。
Create simple pictures using keyboard characters or the mouse.
不过,本章的大部分内容都集中在一些相当简单的内容上:制表符和缩进文本。我们主要通过两种主要模式来描述 Emacs 的行为:基本模式和文本模式。如果您是一名开发人员,您可能希望以适合您所使用的语言的模式编写代码; 详细信息请参见第 9 章。如果您使用 HTML 等标记语言,请参阅第 8 章以获取其他相关信息。
Much of this chapter, though, focuses on some fairly simple stuff: tabs and indenting text. We describe Emacs's behavior in primarily two major modes: fundamental mode and text mode. If you are a developer, you'll probably want to write code in a mode appropriate to the language you're using; see Chapter 9 for details. If you use a markup language like HTML, see Chapter 8 for additional relevant information.
选项卡提供了一种简单的方法 进行一些简单的格式化。当我们修订本书时,我们发现 Emacs 处理选项卡的方式发生了很大变化。本节首先介绍 Emacs 默认情况下如何工作,然后讨论如何更改默认行为以满足您的需求。
Tabs provide an easy way to do some simple formatting. While we were revising this book, we found that the way Emacs handles tabs has changed a great deal. This section describes first how Emacs works by default and then discusses what you can do to change the default behavior to meet your needs.
如果您以文本模式打开一个新文件, 默认情况下,每八个空格设置一个制表符。 (编程模式有自己的缩进行为;有关详细信息,请参阅第 9 章。)
If you open a new file in text mode, tabs are set every eight spaces by default. (Programming modes have their own indentation behavior; see Chapter 9 for details.)
|
按Tab 键。 Press Tab. |
|
|
|
在文本模式或基本模式下按Tab键会插入一个制表符,默认情况下将光标向前移动八列。 Pressing Tab in text mode or fundamental mode inserts a tab character that moves the cursor forward eight columns by default. |
观察当我们输入句子时会发生什么。默认制表位会自动更改。
Watch what happens when we type a sentence. The default tab stops change automatically.
|
类型:这是最好的时光 Enter Tab Tab Type: It was the best of times Enter Tab Tab |
|
|
|
按Tab两次将光标移动到单词was下方,明显少于八列。 Pressing Tab twice moves the cursor under the word was, clearly less than eight columns. |
每次按Tab时,Emacs 都会将光标移动到下一个单词下方。这是许多人在编写代码时所期望的行为。整齐排列的代码更容易阅读。
Every time you press Tab, Emacs moves the cursor under the next word. This is the behavior that many people expect when writing code. Neatly lined up code is easier to read.
当我们尝试此功能时,我们会在每个单词下方进行 Tab 切换,然后按Enter。如果你没有预料到,接下来发生的事情将会令人惊讶。 Emacs 认为换行符是您在该行中键入的唯一字符,因此在后续行上按 Tab 键将使您几乎到达该行的末尾。
As we experimented with this feature, we would tab across under each word, and press Enter. What happens next is surprising if you are not expecting it. Emacs considers that newline to be the only character you typed on the line, so pressing Tab on a subsequent line brings you nearly to the end of the line.
|
重复按Tab 键直至窗口末尾,按Enter 键,然后按 Tab 键一次。 Press Tab repeatedly to the end of the window, press Enter, then press Tab once. |
|
|
|
Emacs 将光标移动到您按Enter 的列。 Emacs moves the cursor to the column where you pressed Enter. |
如果按Enter 键但根本不按Tab 键,缩进级别将移回到左边距。
If you press Enter but don't press Tab at all, the indentation level moves back to the left margin.
例如,如果您正在键入表格,则更改制表符以与每个单词对齐可能会很有帮助。但是,默认选项卡行为可能并不在所有情况下都对您有帮助。如果您有兴趣更改默认行为,请继续阅读,我们将描述如何让 Emacs 执行您希望它执行的操作。
Changing tabs to align with each word can be helpful, if, for example, you're typing tables. However, the default tab behavior may not be helpful to you in all situations. If you are interested in changing the default behavior, read on and we'll describe how to get Emacs to do what you want it to do.
默认情况下(如果文本未对齐
与前一行文本),每八个字符设置制表符。 Emacs 允许您更改制表位的位置。要更改制表位,请输入Mx
edit-tab-stops。*Tab
Stops*出现一个缓冲区。
By default (and if text is not lining up
with some previous line of text),
tabs are set every eight characters. Emacs allows you to change the
positions of the tab stops. To change the tab stops, type M-x
edit-tab-stops. A *Tab
Stops* buffer appears.
|
类型:Mx 编辑制表位 Type: M-x edit-tab-stops |
|
|
|
您现在看到一个制表位标尺;冒号显示制表位的位置。 You now see a tab stop ruler; colons show the locations of tab stops. |
第一行的冒号
显示屏显示制表位当前所在的位置。接下来的两行形成一个标尺,显示该行上每个字符的位置。要插入制表符,请使用
Cf移至所需列,然后键入冒号 (:)。要删除选项卡,请移至所需选项卡,然后按空格键。缓冲区
*Tab Stops*处于覆盖模式,因此这些更改不会更改其他选项卡的位置。确保在显示屏的第一行进行所有编辑。对其他行所做的更改不会产生任何影响。
The colons in the first line of
the display show you where tab
stops are currently located. The next two lines form a ruler that
shows each character position on the line. To insert a tab, use
C-f to move to the desired column,
and then type a colon ( : ). To delete a tab, move to the desired
tab, and press Space. The
*Tab Stops* buffer is in overwrite mode, so these
changes won't change the position of other tabs.
Make sure that you do all your editing in the first line of the
display. Changes made to the other lines won't have
any effect.
当您对制表位感到满意时,请按 抄送 抄送来安装它们。如果不进行任何更改,请按抄送 抄送退出缓冲区。如果您进行了一些更改,然后决定根本不需要它们,请通过键入 Cx k Enter来终止缓冲区。默认制表位仍然有效。
When you're satisfied with the tab stops, press C-c C-c to install them. If you don't make any changes, press C-c C-c to exit the buffer. If you make some changes and then decide you don't want them after all, kill the buffer by typing C-x k Enter. The default tab stops remain in effect.
如果您按抄送抄送来安装它们,新选项卡设置会影响您创建的所有缓冲区,但仅对此 Emacs 会话有效。
If you press C-c C-c to install them, the new tab settings affect all buffers that you create but remain in effect for this Emacs session only.
同样,您可能会觉得此功能无法按您的预期工作。由于 Emacs 的默认行为尝试与前面的行对齐,因此更改制表位实际上仅影响任何缓冲区的第一行。
Again, it may well appear to you that this feature doesn't work as you would expect. Because Emacs's default behavior tries to align with preceding lines, changing tab stops really affects only the first line of any buffer.
在此示例中,我们在第 51 列设置第一个制表符,按Cc Cc安装制表位,并启动一个新缓冲区。在缓冲区开头按Tab 键会将光标立即移动到第 51 列。效果很好。
In this example, we set the first tab at column 51, pressed C-c C-c to install the tab stops, and started a new buffer. Pressing Tab at the beginning of the buffer moves the cursor immediately to column 51. That works fine.
现在我们再按几次Tab 键,然后按Enter 键移动到新行。
Now we press Tab a few more times, followed by Enter to move to a new line.
当我们在第二行按Tab时,Emacs 将换行符视为最后一行上的唯一项目。按Tab 键将我们向右移动到该行的末尾。
When we press Tab on the second line, Emacs views the newline as the only item on the last line. Pressing Tab moves us right to the end of the line.
正如您所看到的,如果您要在表格的行之间或您正在键入的内容之间添加空行,则以这种方式更改制表位的效果有限。您必须通过在键入整个表格后添加空行来解决此问题,也许使用 第 6 章中描述的宏。
As you can see, changing tab stops in this way is of limited efficacy if you're going to add blank lines between rows of your table or whatever you're typing. You'd have to work around this by adding blank lines after typing the whole table, perhaps using a macro as described in Chapter 6.
假设所有这个选项卡 华丽的服饰让你心烦意乱。您不需要上下文相关的缩进;您甚至不想更改制表位。有一种方法可以让 Emacs 像普通的旧打字机一样处理制表符,一次移动超过 8 个字符。[ 1 ]
Let's say that all this tab finery is getting on your nerves. You don't want context-sensitive indenting; you don't even want to change tab stops. There is a way to make Emacs treat tabs just like a regular old typewriter did, moving over eight characters at a time.[1]
要插入刚性的打字机式选项卡,请按Cq Tab。理论上,这应该在文件中插入一个制表符,它看起来像^I.实际上,它将光标严格地向前移动八列。
To insert rigid, typewriter-style tabs, press C-q Tab. In theory, this should insert a tab
character into the file, which would look like ^I.
In practice, it moves the cursor forward rigidly eight columns.
|
类型:Cq 选项卡 Type: C-q Tab |
|
|
|
光标向前移动八列,并且与上一行中的文本不对齐。 The cursor moves eight columns forward and does not align with the text in the previous line. |
Cq Tab实际上在文件中插入了一个制表符。您可以通过按一下Del键将其删除来进行检查。
C-q Tab does in fact insert a tab character in the file. You can check that by erasing it with a single press of the Del key.
选项卡的一个问题是 对于制表符的含义没有通用的定义。在 vi中,默认制表符宽度为四列,而 Emacs 中的默认制表符宽度为八列。此外,Unix 通常倾向于使用八列制表符,而某些操作系统则倾向于使用四个空格。无论 Emacs 在什么平台上运行,默认情况下都使用八列。如果您在 Emacs 中查看其他用户的文件,Emacs 会将选项卡解释为每个选项卡八列,从而造成混乱。因此,您可能需要通过将此行添加到您的.emacs文件来将选项卡默认设置为四列:
One problem with tabs is that there is no universal definition of what a tab means. In vi, the default tab width is four columns versus eight columns in Emacs. Further, Unix generally favors eight columns for tabs while some operating systems tend to use four spaces. Emacs uses eight columns by default no matter what platform it's running on. If you view another user's file in Emacs, Emacs interprets the tabs as eight columns each, throwing things off. For this reason, you might want to set your tab default to four columns by adding this line to your .emacs file:
(setq-默认制表符宽度 4)
(setq-default tab-width 4)
您必须按Cq Tab才能使修改的制表符宽度生效。
You have to press C-q Tab to have the modified tab width take effect.
另一个特点
Emacs 默认行为的一个事实是,当您按Tab时,它可能会插入制表符和空格的组合。尝试擦除一些“制表符”,您会发现它通常不是一个字符,而是相同数量的空格或制表符和空格的组合。当然,这很大程度上取决于制表位与tab-width变量设置的比较。如果您将制表位设置为 6 的倍数,而制表位tab-width为 4 或 8,则 Emacs 将不得不使用制表符和空格的组合来实现所需的制表位。
Another characteristic
of
Emacs's default behavior is the fact that it may
insert a combination of tabs and spaces when you press Tab. Try to erase a few
"tabs" and you'll
see that often it isn't one character, but the
equivalent number of spaces or a combination of tabs and spaces. Of
course, this largely depends on the tab stops compared to setting of
the tab-width variable. If you set tab stops that
are multiples of six while you have a tab-width of
4 or 8, Emacs is going to have to use a combination of tabs and
spaces to achieve the desired tab stops.
如果您希望 Emacs 插入缩进空格而不是制表符,请将此行添加到您的.emacs文件中:
If you want Emacs to insert spaces for indentation rather than tab characters, add this line to your .emacs file:
(setq-默认缩进制表符模式为零)
(setq-default indent-tabs-mode nil)
通过此设置,当您按Tab时,Emacs 仅插入空格。按Cq Tab会插入文字制表符。可以肯定地说,使用此设置您不会意外输入制表符。
With this setting, Emacs inserts only spaces when you press Tab. Pressing C-q Tab instead inserts a literal tab character. It's safe to say you won't enter tab characters accidentally with this setting.
我们刚刚讨论过一个 确保 Emacs 插入空格而不是制表符的方法。但是,如果您继承了一个文件,并且其中包含您想要将其更改为空格的制表符,该怎么办?
We've just talked about a way to make sure that Emacs inserts spaces instead of tabs. But what if you inherit a file and it has tabs that you want to change to spaces?
Emacs 提供了一个命令来消除文件中的制表符。您可以使用制表符进行编辑,然后将所有制表符转换为适当数量的空格,这样文件的外观就不会改变。与制表符不同,空格几乎总是被明确定义的。消除制表符的命令是Mx untabify。有一个相应的命令可以将空格转换为制表符:tabify。然而,我们相信您会接受我们的建议并忘记它。
Emacs provides a command to banish tabs from your files. You can use tabs for editing and then convert all of the tabs to the appropriate number of spaces so that the appearance of your file doesn't change. Unlike tabs, a space is almost always well defined. The command for eliminating tabs is M-x untabify. There's a corresponding command to convert spaces into tabs: tabify. However, we trust that you'll take our advice and forget about it.
untabify命令适用于区域。因此,要使用它,您必须将标记放在缓冲区中的某个位置(最好是在开头),移动到缓冲区中的其他位置(最好是在末尾),然后输入Mx untabify Enter。命令Cx h(用于 mark-whole-buffer)自动将光标置于缓冲区的开头,并将标记置于末尾。它使取消制表变得更加容易,因为您可以使用简单的序列Cx h M-x untabify Enter一次性完成所有操作。
The untabify command works on a region. Therefore, to use it, you must put the mark somewhere in the buffer (preferably at the beginning), move to some other place in the buffer (preferably the end), and type M-x untabify Enter. The command C-x h (for mark-whole-buffer) automatically puts the cursor at the beginning of the buffer and the mark at the end. It makes untabification a bit easier because you can do it all at once with the simple sequence C-x h M-x untabify Enter.
表 7-1显示了我们在本节中介绍的选项卡命令。
Table 7-1 shows the tab commands we've covered in this section.
表 7-1。选项卡命令
Table 7-1. Tab commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
(没有任何) (none) |
编辑制表位 edit-tab-stops |
打开一个名为 的缓冲区 Open a buffer called |
|
(没有任何) (none) |
取消制表 untabify |
将所有制表符更改为相同数量的空格。 Change all tabs into the equivalent number of spaces. |
|
(没有任何) (none) |
制表法 tabify |
尽可能将三个或更多空格的组更改为制表符,而不影响文本位置。 Change groups of three or more spaces to tabs where possible without affecting the text placement. |
Emacs提供了这个能力 缩进段落,就像论文中的块引用一样。它还允许您使用仅缩进段落第一行的段落样式。本节介绍与缩进相关的命令,包括如何更改当前会话的边距。
Emacs provides the ability to indent paragraphs, like a block quote in a paper. It also allows you to use a paragraph style that indents just the first line of a paragraph. This section describes indentation-related commands, including how to change the margins for the current session.
在开始之前,请确保您处于文本模式。查看模式行,如果Text显示该单词,则说明您处于文本模式。如果没有,请键入Mx
text-mode
Enter进入文本模式。
Before we start, make sure you're in text mode. Look
at the mode line and, if the word Text is
displayed, you are in text mode. If not, type M-x
text-mode
Enter to enter text mode.
假设你正在写 一篇论文并希望包含一些缩进的引用块。 Emacs 的默认行为使得这变得理所当然。[ 2 ]完成第一段后,使用制表符或空格缩进到所需的级别,然后开始输入引文。 Emacs 会自动正确填充段落和引用,如以下屏幕所示。
Let's say you're writing a paper and want to include some indented block quotes. Emacs's default behavior makes this a no-brainer.[2] After you finish your first paragraph, use tabs or spaces to indent to the desired level and start typing the quote. Emacs automatically fills the paragraph and the quote correctly, as shown in the following screen.
|
一些缩进的文本: Some indented text: |
|
|
|
Emacs 正确缩进文本并在自动填充模式下正确填充文本。 Emacs indents the text properly and fills it correctly in auto-fill mode. |
如果缩进引用有多个段落怎么办?您可以只按Enter,然后在后续段落的开头再次按 Tab ,也可以按Cj (用于换行和缩进)。按 Cj两次可在段落之间添加一个空行。
What if an indented quote has multiple paragraphs? You could just press Enter and then Tab again at the beginning of subsequent paragraphs or you could press C-j (for newline-and-indent). Pressing C-j twice gives you a blank line between paragraphs.
有些人更喜欢 第一行缩进的段落。了解选项卡的复杂性后,您可能会担心按Tab 缩进段落的开头行会导致 Emacs 在您继续键入时缩进整个段落。说实话,确实会的。
Some people prefer paragraphs in which the first line is indented. Knowing about the intricacies of tabs, you might be concerned that pressing Tab to indent the opening line of your paragraph will incite Emacs to indent the whole paragraph as you continue typing. And it would, to be honest.
Emacs 为此提供了一种特殊模式:段落缩进文本模式。它也可以作为次要模式使用。分别输入Mx paragraph-indent-text-mode或Mx paragraph-ident-minor-mode。如果运行主模式,Emacs 将显示Parindent在模式行上。
Emacs provides a special mode for this purpose: paragraph indent text
mode. It's also available as a minor mode. Enter
either M-x
paragraph-indent-text-mode or M-x
paragraph-ident-minor-mode respectively. If you run the
major mode, Emacs displays Parindent on the mode
line.
当您按Tab 键开始一个段落时,Emacs 会插入一个制表符的空间。当您开始一个新段落时,您不必在中间跳过一行,然后按Tab开始第二段会再次产生一个制表符的空间,而不是像 Emacs 在文本中那样与前一行的第二个单词对齐模式或基本模式。
When you press Tab to start a paragraph, Emacs inserts a tab's worth of space. When you start a new paragraph, you don't have to skip a line in between and pressing Tab to start that second paragraph yields again a tab's worth of space, not aligning with the second word of the previous line as Emacs would do in text mode or fundamental mode.
按Mq可以重新格式化段落,而不会将它们全部混在一起。如果您喜欢缩进段落,这种模式正是您想要的。当您需要缩进块引用时,您可能需要暂时进入文本模式以使其更容易并手动添加段落缩进。
Pressing M-q reformats paragraphs without mushing them all together. If you prefer indented paragraphs, this mode is exactly what you want. When you need to indent a block quote, you may want to temporarily enter text mode to make it easier and add your paragraph indentations manually.
假设你有一个 段落有不同级别缩进的纸张。如果您编辑它们并需要再次填写怎么办?特别是如果段落之间没有空行,Mq 会将所有文本合并成一个大(无缩进)段落。标记有问题的区域并使用特殊的填充命令:Mx fill-individual-paragraphs ,而不是 Mq。 Emacs 保留每个段落的缩进。
Let's say you've got a paper with paragraphs indented at various levels. What if you edit them and need to fill them again? Especially if there are no blank lines in between paragraphs, M-q munges all the text into one big (nonindented) paragraph. Instead of M-q, mark the region in question and use a special fill command: M-x fill-individual-paragraphs. Emacs preserves each paragraph's indentation.
让我们通过一个例子来对比这两个命令。我们将使用之前的 Henry James 示例,但删除段落之间的行以显示 在本例中使用Mq时会发生什么。这些段落需要重新格式化。
Let's contrast these two commands with an example. We'll use our previous Henry James example, but delete the lines between paragraphs to show what happens if you use M-q in this case. These paragraphs need to be reformatted.
|
初始状态: Initial state: |
|
|
|
亨利·詹姆斯的一些示例段落需要重新格式化。 Some sample paragraphs from Henry James, in need of reformatting. |
我们将撤消该命令,将缓冲区标记为区域,并使用fill-individual-paragraphs命令。
We'll undo that command, mark the buffer as a region, and use the fill-individual-paragraphs command.
|
类型:C- _ Cx h Mx 填写个人段落 Enter Type: C- _ C-x h M-x fill-individual-paragraphs Enter |
|
|
|
Emacs 正确地重新填充段落。 Emacs refills the paragraphs properly. |
如果您已经输入了您的 文本没有缩进并且想稍后缩进?两个命令可以处理这个问题,具体取决于您想要将该区域缩进多远。
What if you have already typed your text without indentation and want to indent it later? Two commands can handle this, depending on how far you want to indent the region.
indent -region命令绑定到 CM-\,可以轻松地将区域缩进一级。如果要缩进两级,是不可预测的。 (该命令是为缩进代码而设计的。)
The indent-region command, bound to C-M-\, can indent a region one level easily. If you want to indent two levels, it is unpredictable. (This command is designed for indenting code.)
这是一个例子。第二段被标记为区域。
Here's an example. The second paragraph is marked as a region.
你认为这还不够。
You decide that's not far enough.
因此,您可以看到,如果您缩进一级,则效果很好。如果您尝试使用不同缩进级别的多个段落,缩进区域会将它们全部拉到右侧,将它们与缩进最少的段落对齐,这可能不是您想要的。但是,如果您编写代码,此命令非常适合清理混乱的缩进。
So you can see that this works fine if you're indenting one level. If you try this with multiple paragraphs of different indentation levels, indent-region pulls them all to the right, aligning them with the least indented paragraph, probably not what you intended. If you write code, however, this command is great for cleaning up messy indentation.
另一个选项是标记区域并键入Cx Tab(用于indent-rigidly)。默认情况下,该命令仅缩进一个空格,因此如果您想进一步缩进,则需要为其提供一个参数。例如,要将前一段缩进 15 个空格:
The other option is to mark the region and type C-x Tab (for indent-rigidly). By default, this command indents only one space, so if you want to indent further, you need to give it an argument. For example, to indent the previous paragraph 15 spaces:
|
标记该区域,然后键入:M-15 Cx Tab Mark the region then type: M-15 C-x Tab |
|
|
|
Emacs 将段落缩进 15 个空格。 Emacs indents the paragraph 15 spaces. |
尽管提供论据可能很痛苦,但缩进会严格统一缩进文本,使缩进的段落保持缩进。如果您发现自己想要缩进整个文件,您实际上可能想要更改边距设置,如下一节所述。
Although arguably it can be a pain to supply an argument, indent-rigidly uniformly indents text, leaving indented paragraphs indented. If you find yourself wanting to indent whole files, you may actually want to change the margin settings, as described in the next section.
每当您使用 缩进,您可以使用Mm(返回缩进)移动到一行中的第一个非空白字符。在未缩进的行上,此命令只是将您移动到该行的开头。换句话说,Mm将您带到该行的“逻辑”开头,这就是您键入Ca时通常的意思。
Whenever you are using indentation, you can use M-m (for back-to-indentation) to move to the first nonblank character on a line. On a line that's not indented, this command simply moves you to the beginning of the line. In other words, M-m brings you to the "logical" beginning of the line, which is what you usually mean when you type C-a.
另一个压痕 命令是CMo(用于分割线)。您可以使用此命令创建阶梯效果。将光标移至要放在下一行的文本,然后按CMo。请注意,光标后面必须有一些文本才能使该命令正常工作;如果你在一行的末尾尝试它,它什么也不做。
Another indentation command is C-M-o (for split-line). You can use this command to create a stairstep effect. Move the cursor to the text that you want to put on the next line and press C-M-o. Note that there must be some text following the cursor in order for this command to work properly; if you try it at the end of a line, it does nothing.
Emacs 不是文字处理程序, 但它确实有一些命令可以更改当前会话缓冲区的左右缩进。首先,使用Cx h标记整个缓冲区。然后,您可以使用Mx更改缩进,然后使用以下命令之一:
Emacs is not a word processor, but it does have a few commands that change left and right indentation for a buffer for the current session. First, mark the whole buffer using C-x h. You can then gchange the indention using M-x followed by one of the following commands:
| 增加左边距 |
| 减少左边距 |
| 增加右边距 |
| 减少右边距 |
也可以通过“编辑”菜单使用这些命令。选择“编辑” → “文本属性” → “缩进”以查看选项。
These commands are also available through the Edit menu. Choose Edit → Text Properties → Indentation to see the options.
除非您在这些命令之前使用Cu或M- n提供数字参数,否则 Emacs 会按照变量standard-indent中的字符数增加或减少边距,默认为 4。如果自动填充模式打开,Emacs 还会重新格式化自动的段落。
Unless you supply a numeric argument using C-u or M- n preceding these commands, Emacs increases or decreases the margins by the number of characters in the variable standard-indent, which defaults to 4. If auto-fill mode is on, Emacs also reformats the paragraphs automatically.
保证金设置仅对当前会话和当前缓冲区有效。尽管这些值不会保留到另一个会话,但使用此方法缩进的任何文本在您重新打开文件时仍保持缩进。但是,如果您再次打开该文件并添加一些文本,则它不会缩进;您必须再次设置边距。
Margin settings remain in effect for the current session and the current buffer only. Although the values don't persist to another session, any text that is indented using this method remains indented when you reopen the file. If you open the file again and add some text, however, it is not indented; you have to set the margins again.
当您想要更改整个缓冲区的边距时,这些命令效果最佳。如果您定义较小的区域,这些命令将起作用,但如果您键入更多段落,则无论您是否愿意,边距设置都会保留。如果您已完成文件然后决定更改缩进,这些命令可以正常工作。
These commands work best in cases where you want to change the margin for the whole buffer. If you define a smaller region, the commands work but if you type more paragraphs, the margin settings persist whether you want them to or not. These commands work fine if you've completed the file and then decide to change the indentation.
或者,您可以使用丰富模式设置和保存边距,这是一种次要模式,允许 Emacs 保存文本属性,包括边距设置和字体更改。 有关丰富模式的更多详细信息,请参阅第 10 章。
Alternatively, you can set and save margins using enriched mode, a minor mode that allows Emacs to save text properties, including margin settings and font changes. See Chapter 10 for more details on enriched mode.
填充前缀是一种方法 在段落或文件的每一行的开头放置特定的字符串。开发人员会立即将注释视为潜在的填充前缀。在撰写电子邮件或新闻帖子时,电子邮件程序通常会插入一个字符串来帮助读者区分讨论的主题。对于我们这些编写文本文件的人来说,填充前缀可用于在段落或任何相关字符串中插入空格。
Fill prefixes are a way of putting a certain string of characters at the beginning of each line in a paragraph or a file. Developers will immediately think of comments as a potential fill prefix. When writing email or newsposts, email programs often insert a string to help readers distinguish the threads of a discussion. For those of us writing text files, fill prefixes can be used to insert whitespace in paragraphs or any relevant string of characters.
术语“填充 前缀”来自 Emacs 调用自动换行 自动填充 模式的事实;换句话说,填充前缀是 Emacs 在进行自动换行时应在每行开头插入的字符串(或为每行添加“前缀”)。
The term fill prefix comes from the fact that Emacs calls word wrap auto-fill mode; in other words, a fill prefix is a string that Emacs should insert at the beginning of each line (or "prefix" each line with) when doing word wrap.
要使用填充前缀,最好处于自动填充模式。如果您的模式行Fill上有说明,则您已经处于自动填充模式。如果没有,请输入Mx
auto-fill-mode
Enter。
To use fill prefixes, it's best to be in auto-fill
mode. If your mode line says Fill on it,
you're already in auto-fill mode. If it
doesn't, type M-x
auto-fill-mode
Enter.
现在假设您想要缩进一个字母。对于信件的第一行,手动输入缩进,例如八个空格。然后输入Cx
。 (对于set-fill-prefix)。 Emacs 在迷你缓冲区中显示消息:fill prefix " "。然后开始正常输入。每当您输入超出右边距并且 Emacs 为您换行时,它会自动在行首插入八个空格的缩进。
Now let's assume that you want to indent a letter.
For the first line of the letter, type your indentation by
hand—say, eight spaces. Then type C-x
. (for set-fill-prefix).
Emacs displays the message: fill prefix " " in the
minibuffer. Then start typing normally. Whenever you type past the
right margin and Emacs breaks a line for you, it automatically
inserts your eight-space indentation at the beginning of the line.
这是一个稍微令人兴奋的例子。没有理由填充前缀必须是空格;它们可以是您选择的任何内容。假设您要向朋友发送一封电子邮件以宣布一项独特的活动,并且您需要一个引人注目的填充前缀。
Here's a slightly more exciting example. There's no reason that fill prefixes must to be spaces; they can be anything you choose. Assume that you're sending an email message to your friends to announce a unique event and you want an eye-catching fill prefix.
|
类型:骑大象派对!!! CX . Type: Elephant Riding Party!!! C-x . |
|
|
|
键入前缀,然后键入Cx。来设置它。 Type the prefix, then C-x . to set it. |
设置前缀后,您就可以正常输入消息了。
Once you've set the prefix, you can type your message normally.
|
类型:时间。 。 。动物园。 Type: The time . . . the zoo. |
|
|
|
Emacs 在消息每行的开头插入填充前缀。 Emacs inserts the fill prefix at the beginning of each line of the message. |
你必须输入“骑大象派对!!!”只有一次; Emacs 自动插入其余部分。以下是您可能想了解的有关填充前缀的一些信息:
You had to type "Elephant Riding Party!!!" only once; Emacs inserted the rest automatically. Here are some things you might want to know about fill prefixes:
Emacs 从不将填充前缀应用于段落的第一行。显然你不能将它应用到第一段的第一行(你必须在某个地方输入它)。但 Emacs 无法将其应用于 任何段落的第一行。换句话说,如果“骑大象”消息有两个段落,您必须输入(或拉出)短语“骑大象派对!!!”在第二段的开头。
Emacs never applies the fill prefix to the first line of a paragraph. You obviously can't apply it to the first line of the first paragraph (you have to type it somewhere). But Emacs can't apply it to the first line of any paragraph. In other words, if the "elephant riding" message had two paragraphs, you'd have to type (or yank) the phrase "Elephant Riding Party!!!" at the beginning of the second paragraph.
但是,您不需要再次设置填充前缀。 Emacs 为后续段落中除第一行之外的所有行提供前缀。它只是对任何段落的首行感到困惑。
However, you don't need to set the fill prefix again. Emacs supplies your prefix for all lines but the first in subsequent paragraphs. It just gets confused about the initial line of any paragraph.
一旦开始使用填充前缀,如何将其关闭?没有什么特殊的命令。您要做的就是将光标放在左边距并输入Cx。定义一个新的空填充前缀。
Once you've started using a fill prefix, how do you turn it off? There's no special command. All you do is put the cursor at the left margin and type C-x . to define a new, empty fill prefix.
您可以编辑带有填充前缀的段落,然后使用 Mq重新格式化它们,只要填充前缀仍然定义即可。如果您清除了填充前缀,Emacs 会重新格式化该段落,而不考虑填充前缀。如果稍后需要重新格式化段落,请在取消填充前缀后重新定义它,然后输入Mq。
You can edit paragraphs with fill prefixes, then reformat them with M-q, as long as the fill prefix is still defined. If you have cleared the fill prefix, Emacs reformats the paragraph without regard to the fill prefix. If you need to reformat your paragraphs later, after you've canceled the fill prefix, define it again and then type M-q.
表 7-2列出了缩进 我们已经讨论过的命令。
Table 7-2 lists the indentation commands we've discussed.
表 7-2。缩进命令
Table 7-2. Indentation commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
Cj C-j |
换行和缩进 newline-and-indent |
移至下一行并缩进至当前级别。 Move to the next line and indent to the current level. |
|
(没有任何) (none) |
段落缩进文本模式 paragraph-indent-text-mode |
用于编写首行缩进并且段落之间没有空行的段落的主要模式。 A major mode for writing paragraphs with indented first lines and no blank lines between paragraphs. |
|
(没有任何) (none) |
段落缩进小模式 paragraph-indent-minor-mode |
次要模式相当于段落缩进文本模式。 The minor mode equivalent of paragraph-indent-text mode. |
|
(没有任何) (none) |
填写个别段落 fill-individual-paragraphs |
重新格式化缩进段落,保留缩进。 Reformat indented paragraphs, preserving indentation. |
|
CX 选项卡 C-x Tab |
严格缩进 indent-rigidly |
缩进一栏;前言以Cu 或Mn指定多个列。 Indent one column; preface with C-u or M-n to specify multiple columns. |
|
厘米-\ C-M-\ |
缩进区域 indent-region |
缩进区域以匹配该区域中的第一行。 Indent a region to match the first line in the region. |
|
毫米 M-m |
回到缩进 back-to-indentation |
将光标移动到一行中的第一个非空白字符。 Move the cursor to the first non-whitespace character on a line. |
|
奇摩 C-M-o |
分割线 split-line |
在光标位置分割行并将其缩进到光标位置的列。 Split the line at the cursor position and indent it to the column of the cursor position. |
|
(无)编辑 → 文本属性 → 缩进 → 缩进更多 (none)Edit → Text Properties → Indentation → Indent More |
增加左边距 increase-left-margin |
默认情况下,将缓冲区的左缩进级别增加四个字符。 Increase the left indentation level for the buffer by four characters by default. |
|
(无)编辑 → 文本属性 → 缩进 → 少缩进 (none)Edit → Text Properties → Indentation → Indent Less |
减少左边距 decrease-left-margin |
默认情况下,将缓冲区的左缩进级别减少四个字符。 Decrease the left indentation level for the buffer by four characters by default. |
|
(无)编辑 → 文本属性 → 缩进 → 向右缩进 更多 (none)Edit → Text Properties → ndentation → Indent Right More |
减少右边距 decrease-right-margin |
默认情况下,将缓冲区的右侧缩进级别减少四个字符。 Decrease the right indentation level for the buffer by four characters by default. |
|
(无)编辑 → 文本属性 → 缩进 → 向左缩进更多 (none)Edit → Text Properties → Indentation → Indent Left More |
增加右边距 increase-right-margin |
默认情况下,将缓冲区的右侧缩进级别增加四个字符。 Increase the right indentation level for the buffer by four characters by default. |
|
CX . C-x . |
设置填充前缀 set-fill-prefix |
使用光标所在列之前的信息作为段落每一行的前缀;在第 1 列中键入此命令会取消填充前缀。 Use the information up to the cursor column as a prefix to each line of the paragraph; typing this command in column 1 cancels the fill prefix. |
另一个常见的格式化任务是 居中文本。例如,您可能希望将文档标题或文档中的各个标题居中。 Emacs 提供中心线、段落和区域的命令。
Another common formatting task is centering text. For example, you might want to center the title of a document or individual headings within a document. Emacs provides commands to center lines, paragraphs, and regions.
在文本模式下,您可以通过以下方式将行居中只需键入您想要居中的行(或移动到现有行的任意位置),然后按 Ms。
In text mode, you can center a line by simply typing the line you want to center (or moving anywhere on an existing line), and then pressing M-s.
您还可以将段落居中 和地区。在这两种情况下,Emacs 都是逐行居中而不是块居中。要将段落居中,请使用命令MS(对于center-paragraph);要将区域居中,请使用 Mx center-region。例如,假设您要将以下引文居中。
You can also center paragraphs and regions. In both cases, Emacs does line-by-line centering rather than block centering. To center a paragraph, use the command M-S (for center-paragraph); to center a region, use M-x center-region. For example, let's say you want to center the following quotation.
在这种情况下,逐行 居中看起来相当艺术。但有时您可能希望 Emacs 能够进行块居中。您可以使用 本章前面讨论的indent-rigidly命令来复制此效果。您只需调整缩进,看看文本块应该缩进多远才能看起来居中。
In this case, line-by-line centering looks rather artistic. But there are times when you might wish Emacs did block centering. You can replicate this effect by using the indent-rigidly command, discussed earlier in this chapter. You just have to play with the indentation to see how far the block of text should be indented to look centered.
还有一种居中选择。您可以通过选择“编辑” → “文本属性” → “对齐方式” → “居中”来更改对齐方式。此命令适用于选择的任何文本。
There's one more choice for centering. You can change justification by choosing Edit→ Text Properties→ Justification→ Center. This command works on whatever text is selected.
表 7-3列出了用于使文本居中的命令。
Table 7-3 lists the commands used to center text.
表 7-3。居中命令
Table 7-3. Centering commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
多发性硬化症 M-s |
中心线 center-line |
将光标所在的行居中。 Center the line the cursor is on. |
|
多发性硬化症 M-S |
中心段落 center-paragraph |
将光标所在的段落居中。 Center the paragraph the cursor is on. |
|
(没有任何) (none) |
中心区域 center-region |
将当前定义的区域居中。 Center the currently defined region. |
|
(无)编辑 → 文本属性 → 对齐方式 → 居中 (none)Edit → Text Properties → Justification → Center |
设置调整中心 set-justification-center |
居中选定的文本。 Center selected text. |
当你写东西的时候, 无论是一本书、一篇长论文还是一份技术规范,在进行过程中获得组织感通常都很困难。如果没有结构感,就很难将大纲平滑地扩展为更长的论文,或者在进行过程中重新组织论文。这些词语妨碍了你的标题,让人很难只见树木。
When you're writing something, whether it's a book, a long paper, or a technical specification, getting a sense of organization as you go along is frequently difficult. Without a sense of structure, it is hard to expand an outline smoothly into a longer paper or to reorganize a paper as you go along. The words get in the way of your headings, making it hard to see the forest for the trees.
大纲模式为这个问题提供了内置的解决方案。此模式使您能够根据文本与文档结构的关系有选择地隐藏或显示文本。例如,您可以隐藏除标题之外的所有文档文本,从而让您了解文档的形状。当您查看标题时,您可以专注于结构,而不必担心各个段落。解决了结构问题后,您可以使文本重新出现。
Outline mode provides a built-in solution to this problem. This mode gives you the ability to hide or display text selectively, based on its relationship to the structure of your document. For example, you can hide all of your document's text except for its headings, thereby giving you a feel for the document's shape. When you're looking at the headings, you can focus on structure without being concerned about individual paragraphs. When you've solved your structural problems, you can make the text reappear.
大纲模式对于具有多层标题的文档(或长程序)比包含很少文本的简单大纲更有用。文档越长,就越难快速了解整体结构;在这种情况下,大纲模式隐藏和显示部分文本的能力就派上用场了。
Outline mode is more useful for documents with several levels of headings (or for long programs) than for plain outlines containing very little text. The longer a document is, the harder it is to get a quick feel for the overall structure; it is in such a situation that outline mode's ability to hide and show portions of the text comes in handy.
大纲模式要求您遵循大纲或文档中的一些特殊约定。图 7-1显示了传统格式的轮廓和为轮廓模式准备的相同轮廓。左边,我们展示了一个“传统”的轮廓;在右侧,我们在准备好轮廓模式后显示了相同的轮廓:
Outline mode requires you to follow some special conventions in your outline or document. Figure 7-1 shows an outline in traditional format and the same outline prepared for outline mode. On the left, we show a "traditional" outline; on the right, we show the same outline, after being prepared for outline mode:
传统大纲使用罗马数字、大写字母、数字和小写字母的分层方案来表示标题级别 1 到 4,而大纲模式默认情况下期望看到一个星号 (*) 表示第一级标题,两个星号表示第二级标题。级别标题等。不以 * 开头的行(例如“本书包罗万象”)称为 正文行。请注意,Emacs 期望在第一列中看到星号。您可以使用传统的轮廓缩进,前提是星号从第一列开始。[ 3 ]
Whereas traditional outlines use a hierarchical scheme of Roman numerals, uppercase letters, numbers, and lowercase letters for heading levels 1 through 4, outline mode by default expects to see one asterisk (*) for a first-level heading, two for a second-level heading, and so on. Lines that don't start with an *, such as "This book is all-inclusive," are referred to as body lines. Notice that Emacs expects to see the asterisk in the first column. You can use traditional outline indentation, provided that the asterisks start in the first column.[3]
示例轮廓只有两条主体线。不过,随着我们编写这本书,我们会逐渐添加越来越多的正文:“这本书包罗万象”将被前言的很大一部分所取代,而大纲后面的其他正文行将变成正文对于第 1 章。如果使用得当,大纲模式可以消除大纲和书写之间的区别。随着你的大纲不断发展并变得更加详细,它可以逐渐成为你的论文。
The sample outline has only two body lines. As we developed the book, though, we'd gradually add more and more body: "This book is all-inclusive" would be replaced by a substantial chunk of the preface, and other body lines later in the outline would turn into the text for Chapter 1. When used properly, outline mode removes the distinction between outlining and writing. As your outline grows and becomes more detailed, it can gradually become your paper.
开始大纲
模式,输入Mx
Outline-mode
Enter。Outline出现在模式行上。 (大纲模式也可以作为次要模式使用;我们将在本节稍后讨论。)
To start outline
mode,
type M-x
outline-mode
Enter. Outline appears on
the mode line. (Outline mode is also available as a minor mode;
we'll discuss that later in this section.)
进入大纲模式后,您可以使用特殊命令从大纲的一个部分快速移动到另一部分。Cc Cn移至下一个标题或副标题;Cc Cp移至上一个。Cc Cf移动到同一级别的下一个标题,因此您可以使用此命令在整个大纲中从一个一级标题移动到另一个标题,或者在给定条目中从一个二级标题移动到另一个标题。Cc Cb向后移动到同一级别的上一个标题。如果您想从二级标题移动到一级标题(在大纲结构中向上一级),请键入Cc Cu。 (如果您已经处于第一级标题,Cc Cu会发出蜂鸣声,因为它无法移动到更高级别。)图 7-2说明了这些光标命令如何在我们的示例大纲上工作。
After you are in outline mode, you can use special commands to move quickly from one part of the outline to another. C-c C-n moves to the next heading or subheading; C-c C-p moves to the previous one. C-c C-f moves to the next heading of the same level, so you can use this command to move from one first-level heading to another throughout the outline, or from one second-level heading to another within a given entry. C-c C-b moves backward to the previous heading of the same level. If you want to move from a second-level heading to its first-level heading, up a level in the outline structure, you type C-c C-u. (If you are on a first-level heading already, C-c C-u beeps because it can't move to a higher level.) Figure 7-2 illustrates how these cursor commands would work on our sample outline.
这些命令可以轻松解决许多组织问题。如果您经常想,“我知道我正在写有关小部件的文章,但我不记得我想要表达的更重要的观点”,请输入Cc Cu以进入大纲的下一个更高级别。如果您想了解小部件与该部分中其他主题的关系,请使用 Cc Cb和Cc Cf前后移动到其他标题。
These commands make it easy to solve a lot of organizational problems. If you often think, "I know I'm writing about widgets, but I can't remember the bigger point I'm trying to make," type C-c C-u to get to the next higher level of the outline. If you want to figure out how widgets relate to the other topics within the section, use C-c C-b and C-c C-f to move backward and forward to your other headings.
轮廓最重要的特征 模式是有选择地隐藏或显示文本的不同部分的能力。能够使用大纲模式查看长文档的骨架视图是其最佳功能;当您可以隐藏除标题之外的所有内容并查看其是否连贯或需要重新组织时,评估文档的结构就会容易得多。
The most important feature of outline mode is the ability to selectively hide or show different portions of your text. The ability to see a skeletal view of a long document with outline mode is its best feature; it's much easier to evaluate the structure of a document when you can hide everything but the headings and see whether it is coherent or in need of some reorganization.
尽管听起来像是侦探小说中的内容,但 隐藏正文命令Cc Ct会隐藏所有正文(或文本)行,但使所有标题(以星号开头的行)可见。无论 Emacs 在哪里隐藏文本,它都会在相应的标题行上放置一个省略号 (...)。省略号告诉您存在一些隐藏文本。缓冲区本身没有被修改;如果您观察模式行的左侧,您会注意到,指示已修改缓冲区的星号不会出现。如果您在隐藏某些文本时保存文件并退出,Emacs 会将隐藏文本与您看到的显示内容一起保存;隐藏文本绝不意味着丢失文本。下次您阅读该文件时,Emacs 将显示所有隐藏的文本。
Although it sounds like something out of a detective novel, the hide-body command, C-c C-t, hides all the body (or text) lines but leaves all the headings (lines that begin with an asterisk) visible. Wherever Emacs hides text, it places an ellipsis (...) on the corresponding heading line. The ellipsis tells you that some hidden text is present. The buffer itself is not modified; you'll notice, if you watch the left side of the mode line, that the asterisks that indicate a modified buffer don't appear. If you save a file and exit while some text is hidden, Emacs saves the hidden text along with what you see displayed; hiding text in no way implies losing text. The next time you read the file, Emacs shows all text that was hidden.
使用hide-body命令是了解长文档结构的好方法。然后,您可以输入抄送 抄送,然后仅查看标题而不查看文本。例如,让我们从上面给出的简单轮廓开始并隐藏正文。
Using the hide-body command is a good way to get a feel for the structure of a long document. You can then type C-c C-t and see only the headings without the text. For example, let's start with the simple outline we gave above and hide the body.
|
类型:抄送抄送 Type: C-c C-t |
|
|
|
身体被隐藏;椭圆向我们展示了身体线条的位置。 The body is hidden; ellipses show us where body lines are. |
要显示文件中的所有隐藏文本(无论是标题还是正文),请键入 Cc Ca(对于show-all)。这些命令hide-body和show-all对整个轮廓起作用。与hide-body类似的命令是 hide-sublevels、Cc Cq。此命令仅显示第一级标题,让您了解正在处理的文档中的主要部分。
To show all the hidden text in a file, whether headings or body, type C-c C-a (for show-all). These commands, hide-body and show-all, work on the outline as a whole. A command similar to hide-body is hide-sublevels, C-c C-q. This command shows only first-level headers, giving you a feel for the major sections in the document you're working on.
现在你知道如何隐藏了 和显示文本一样,我们来讨论一下隐藏文本的一些属性。在文档的某些部分处于隐藏状态时对其进行编辑通常很有用,这是对文档结构进行重大更改的好方法,但您应该注意一些危险。假设您已使用大纲模式隐藏了所有文本,并且仅显示标题,从而为您提供了文档的真实“大纲”。如果您移动包含隐藏文本和与其关联的标题的标题,则当您移动可见文本时,隐藏的所有内容都会移动。稍后,当您“显示”整个文档时,隐藏的文本将显示在新位置 - 您移动的标题下方。同样,如果删除标题,也会删除所有隐藏文本。
Now that you know how to hide and show text, let's discuss some of the properties of hidden text. Editing a document while some of it is hidden is often useful—it's a great way to make major changes in document structure—but there are some dangers that you should be aware of. Let's say you've hidden all text with outline mode and only the headings are showing, giving you a true "outline" of your document. If you move a heading that has hidden text and headings associated with it, everything that is hidden moves when you move the visible text. Later, when you "show" all of the document, the hidden text appears in its new location—underneath the heading that you moved. Similarly, if you delete a heading, you delete all hidden text as well.
此功能使移动文本块变得容易。然而,有一些事情需要注意。如果删除条目后面的省略号,Emacs 也会删除隐藏信息。值得赞扬的是,Emacs 试图阻止你这样做;它不允许您使用Del 键或使用普通光标命令(如Cb)将光标移动到其上来删除省略号。但是,如果您坚持不懈,可以使用Ck等删除省略号(及其代表的文本)。如果这样做,Emacs 将删除隐藏文本。输入Cy会拉出删除省略号时删除的隐藏文本;撤消命令C -_恢复省略号。我们的建议是在删除文本之前显示文本,以便您可以看到自己在做什么。另一方面,当您移动大纲的各个部分时,隐藏文本会很有帮助,这样您就可以记住结构。
This feature makes moving blocks of text easy. However, there are some things to watch out for. If you delete the ellipsis following an entry, Emacs deletes the hidden information as well. To its credit, Emacs tries to keep you from doing this; it does not allow you to delete the ellipsis using the Del key or using normal cursor commands like C-b to move the cursor onto it. However, if you're persistent you can delete the ellipses (and the text it represents) using, for example, C-k. If you do so, Emacs deletes the hidden text. Typing C-y yanks the hidden text that you killed when you deleted the ellipsis; the undo command, C-_, restores the ellipsis. Our advice is to display text before deleting it so you can see what you're doing. On the other hand, when you are moving sections of an outline around, it is helpful to do sowhile text is hidden so you can keep the structure in mind.
将隐藏文本移动到不处于大纲模式的缓冲区时要小心。假设您的大纲以标题结尾,后跟省略号。当标记该部分以移动到另一个缓冲区时,请确保该区域包含省略号后面的换行符(例如,移动到下一行的开头)。如果您只是将光标放在省略号后面,Emacs 将仅复制标题,而不复制隐藏文本。我们不确定为什么。移过换行符会正确复制正文和标题,并以文本模式将其粘贴到缓冲区中显示所有隐藏文本。
Be careful when moving hidden text to a buffer that's not in outline mode. Let's say that your outline ends with a heading followed by an ellipsis. When marking that section to move to another buffer, make sure the region includes the newline following the ellipsis (for example, move to the beginning of the next line). If you simply place the cursor following the ellipsis, Emacs copies only the header, not the hidden text. We're not sure why. Moving past the newline copies the body as well as the heading correctly, and pasting it into a buffer in text mode shows all the hidden text.
当你搬家时 文本周围,可以方便地标记大纲的一部分,然后移动它或将其提升或降级,正如我们接下来讨论的那样。要标记大纲的一部分(当前标题及其子标题),请键入Cc @(对于大纲标记子树)。然后,您可以剪切或粘贴已标记的部分。您可能需要键入Cx Cx来验证该区域是否已正确标记。
When you're moving text around, it's convenient to be able to mark a section of the outline and then move it or promote or demote it a level, as we'll discuss next. To mark a section of the outline (the current heading and its children), type C-c @ (for outline-mark-subtree). You can then cut or paste the section you've marked. You might want to type C-x C-x to verify that the region is marked correctly.
很多时候当你写作的时候,
你发现某个标题确实应该提升或降级。要提升标题,请输入Cc C-^。要将其降级,请抄送 Cv。 (请注意,巧妙地尝试使键绑定表明您正在使用^和向上或向下移动标题v。)这会自动更改相关标题的标记。换句话说,提升二级标题会删除星号,使其成为一级标题。您会发现移动到下一个和上一个标题的命令Cc Cn和Cc Cp在升级和降级部分时非常有用。
Often as you're writing,
you
find that a certain heading should really be promoted or demoted a
level. To promote a heading, type C-c
C-^. To demote it a level, C-c
C-v. (Note the clever attempt to make the key bindings
indicate that you're moving headings up or down a
level using ^ and v.) This
automatically changes the markings for the heading in question. In
other words, promoting a second-level heading removes an asterisk,
making it a first-level heading. You'll find the
commands to move to the next and previous headings, C-c C-n and C-c
C-p, helpful when you are promoting and demoting sections.
但是,如果您不仅想降级标题,还想降级子树怎么办?甚至整个轮廓?目前,您必须编写一个 Lisp 函数来执行此操作(或使用其他人的函数)。像这样的几个函数已经由专家编写并发布到网上,但在撰写本文时,这些函数都不是 Emacs 的一部分。我们希望这个功能尽快被纳入。
But what if you want to demote not just a heading but a subtree? Or even the entire outline? At the moment, you'd have to write a Lisp function to do that (or use someone else's). Several functions like this have been written by gurus and posted online, but none are part of Emacs at this writing. We hope this function is incorporated soon.
大纲模式也是
可以作为次要模式使用,这样您就可以从属于您最喜欢的主要模式来使用它。要将大纲模式作为次要模式启动,请输入Mxoutline
-minor-mode;Outl
出现在模式行上。从某些方面来说,这种模式不太方便;在大纲次要模式下,与大多数大纲模式命令使用的简单抄送前缀不同,您必须在所有命令前面加上抄送
@,以避免干扰主要模式的常用抄送命令。因此,如果您想向下移动到下一个标题(大纲模式下的Cc
Cn
命令),您可以键入Cc
@
Cn。
Outline mode is also
available as a minor mode so that you
can use it subordinately to your favorite major mode. To start
outline mode as a minor mode, type M-x
outline-minor-mode; Outl
appears on the mode line. In some ways, this mode is less convenient;
rather than the simple C-c prefix
you use for most outline mode commands, in outline minor mode, you
must preface all commands with C-c
@ instead, to avoid interfering with
the usual C-c commands of the major
mode. So, if you want to move down to the next heading (the C-c
C-n
command in outline mode), you would type C-c
@
C-n instead.
请注意,混合轮廓主要模式和轮廓次要模式不仅是多余的,而且可能很危险。在主模式打开时打开次模式可能会使 Emacs 感到困惑。退出大纲模式,然后根据需要进入大纲次要模式。
Please note that mixing outline major mode and outline minor mode is not only redundant but can be dangerous. Turning on the minor mode while the major mode is on can confuse Emacs. Exit outline mode, then enter outline minor mode if you wish.
表 7-4总结了大纲模式命令。在下一节中,我们将讨论另一种专门的编辑方法:使用矩形进行编辑。
Table 7-4 summarizes outline mode commands. In the next section, we discuss another specialized editing method: editing with rectangles.
表 7-4。大纲模式命令
Table 7-4. Outline mode commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
(没有任何) (none) |
轮廓模式 outline-mode |
切换轮廓模式。 Toggle outline mode. |
|
抄送 Cn 标题 → 下一页 C-c C-n Headings → Next |
大纲下一个可见标题 outline-next-visible-heading |
移至下一个标题。 Move to the next heading. |
|
抄送 Cp 标题 → 上一页 C-c C-p Headings → Previous |
大纲-上一个-可见-标题 outline-previous-visible-heading |
移至上一个标题。 Move to the previous heading. |
|
抄送抄送 标题 → 下一个相同级别 C-c C-f Headings → Next Same Level |
大纲向前同级 outline-forward-same-level |
移至同一级别的下一个标题。 Move to the next heading of the same level. |
|
抄送 Cb 标题 → 上一个相同级别 C-c C-b Headings → Previous Same Level |
大纲向后同级 outline-backward-same-level |
移至同一级别的上一个标题。 Move to the previous heading of same level. |
|
抄送铜 标题 → 向上 C-c C-u Headings → Up |
大纲向上标题 outline-up-heading |
上移一级标题。 Move up one heading level. |
|
抄送抄送 隐藏 → 隐藏正文 C-c C-t Hide → Hide Body |
隐藏体 hide-body |
隐藏所有身体线条。 Hide all body lines. |
|
Cc Ca 显示 → 显示全部 C-c C-a Show → Show All |
显示所有 show-all |
显示隐藏的一切。 Show everything that's hidden. |
|
抄送 Cq 隐藏 → 隐藏子级别 C-c C-q Hide → Hide Sublevels |
隐藏子级别 hide-sublevels |
仅显示第一级标题。 Display first level headers only. |
|
抄送公司 隐藏 → 隐藏其他 C-c C-o Hide → Hide Other |
隐藏其他 hide-other |
隐藏当前子树之外的所有文本和标题。第一级标题显示。 Hide all text and headings outside the current subtree. First level headers show. |
|
抄送@ C-c @ |
轮廓标记子树 outline-mark-subtree |
标记当前标题和所有子级别。 Mark the current header and all sublevels. |
|
抄送C-^ C-c C-^ |
大纲推广 outline-promote |
将当前标题提升一级。 Promote the current heading one level. |
|
抄送CV C-c C-v |
大纲降级 outline-demote |
将当前标题降一级。 Demote the current heading one level. |
|
抄送 Cd 隐藏 → 隐藏子树 C-c C-d Hide → Hide Subtree |
隐藏子树 hide-subtree |
隐藏与给定标题相关的副标题和正文。 Hide subheads and body associated with a given heading. |
|
抄送抄送 隐藏 → 隐藏条目 C-c C-c Hide → Hide Entry |
隐藏条目 hide-entry |
隐藏与特定标题关联的正文(不是子标题及其正文)。 Hide the body associated with a particular heading (not subheads and their bodies). |
|
Cc Cl 隐藏 → 隐藏叶子 C-c C-l Hide → Hide Leaves |
皮叶 hide-leaves |
隐藏特定标题的正文及其所有子标题的正文。 Hide the body of a particular heading and the bodies of all its subheads. |
|
抄送 Cs 显示 → 显示子树 C-c C-s Show → Show Subtree |
显示子树 show-subtree |
显示与给定标题关联的副标题和文本。 Show the subheads and text associated with a given heading. |
|
Cc Ce 展会 → 展会入口 C-c C-e Show → Show Entry |
演出条目 show-entry |
显示与特定标题相关的正文(不是副标题及其正文)。 Show the body associated with a particular heading (not subheads and their bodies). |
|
抄送 Ck 显示 → 显示分支 C-c C-k Show → Show Branches |
显示分支 show-branches |
显示标题正文及其所有副标题的正文。 Show the body of a heading and bodies of all its subheads. |
|
抄送选项卡 显示 → 显示子项 C-c Tab Show → Show Children |
表演儿童 show-children |
显示与特定标题相关的下一级副标题(没有正文)。 Show the next level of subheads associated with a particular heading (none of body text). |
[ 3 ]当然,文档完成后,您会想要删除星号。您可以使用查询替换将星号样式标题更改为适合您首选格式样式的标题。找到最低级别的标题并首先进行替换。如果您有第三级标题,请将所有出现的 *** 替换为第三级标题的标记,然后转到第二级标题,最后转到第一级标题。不过,要小心一级标题;文件中很可能存在与标题无关的星号;在星号前面加上Cq Cj以确保您得到一个新行开始的星号。另一种方法是使用 Eric Pement 的 awk 脚本。http://www.student.northpark.edu/pemente/awk/outline_classic11.awk.txt中的脚本 将大纲模式大纲转换为经典大纲,而http://www.student.northpark.edu/pemente中的脚本将大纲模式大纲转换为经典大纲/awk/outline_numbered11.awk.txt 转换为编号大纲。
[3] Of course, after the document is complete, you'll want to remove the asterisks. You can use a query-replace to change the asterisk-style headers into headers that are appropriate for your preferred formatting style. Find the lowest-level heading and do its replacement first. If you have third-level headings, replace all occurrences of *** with the mark-up for a third-level heading, then move on to second-level headings, and finally first-level headings. Be careful on first-level headings, though; there may well be asterisks in the file that are unrelated to headings; preface the asterisk with C-q C-j to ensure that you get an asterisk that starts on a new line. Another approach is to use Eric Pement's awk scripts. The script at http://www.student.northpark.edu/pemente/awk/outline_classic11.awk.txt converts an outline mode outline to a classic outline while the script at http://www.student.northpark.edu/pemente/awk/outline_numbered11.awk.txt converts to a numbered outline.
当您将区域标记为 移动或删除时,它们总是覆盖窗口的整个宽度。按区域编辑对于您在 Emacs 中所做的大部分工作来说都很好。但是如果您想编辑表格怎么办?区域覆盖窗口的整个宽度,因此它们无法处理列。 Emacs 提供了另一种方法来定义要删除、复制和移动的区域:使用 矩形。矩形顾名思义:使用特殊矩形编辑命令定义和操作的矩形区域。当您想要移动或删除垂直信息列时,使用矩形进行编辑非常有用。例如,移动表的列或重新排列数据集中的字段。
When you mark regions to move or delete, they always cover the full width of the window. Editing by region is fine for most of the work that you do in Emacs. But what if you wanted to edit a table? Regions cover the full width of the window, so they can't handle columns. Emacs offers another way to define areas to delete, copy, and move around: using rectangles. Rectangles are just what they sound like: rectangular areas that you define and manipulate using special rectangle editing commands. Editing with rectangles is useful whenever you want to move or delete vertical columns of information; for instance, moving a column of a table or rearranging fields in a dataset.
例如,假设您要编辑下表,将“小时”列移至右侧。无法使用区域来执行此操作,但如果您学习一些矩形编辑命令,则很容易做到。
For example, let's say you want to edit the following table, moving the "Hours" column to the right side. There's no way to do this using regions, but it's easy to do if you learn some rectangle editing commands.
定义矩形的方式与定义区域的方式相同;标记区域后使用的命令告诉 Emacs 是否要使用区域或矩形。 (这是放开鼠标并使用键盘命令来标记文本的好时机。当您使用矩形时,突出显示保持水平状态,并且只会在您开始以矩形方式思考时让您感到困惑。当然,没有什么问题使用鼠标快速移动光标;只是不要使用它来突出显示文本。)
You define a rectangle the same way you define a region; the commands you use after marking the area tell Emacs whether you want to work with a region or a rectangle. (This is a good time to let go of your mouse and use keyboard commands for marking the text. Highlighting remains horizontal when you're working with rectangles and will only confuse you as you begin to think rectangularly. Of course, there's nothing wrong with using the mouse to move the cursor quickly; just don't use it to highlight text.)
在我们开始使用这些列之前,请使用 Cx h选择缓冲区并通过键入 Mx untabify取消制表符。矩形编辑最适合不包含制表符的文件。
Before we start working with these columns, select the buffer with C-x h and untabify it by typing M-x untabify. Rectangle editing works best with files that do not contain tab characters.
要定义矩形,请将光标移动到左上角并按C-Space设置标记,然后将光标移动到矩形的右下角。当到达矩形的右下角时,再向前移动一个字符。为什么要把一个角色移得更远呢?请记住,定义区域时,光标所在的字符 不属于该区域。 (标记所在的字符是该区域的一部分。)
To define a rectangle, move the cursor to the upper-left corner and set the mark by pressing C-Space, then move the cursor to the lower-right corner of the rectangle. Once you're at the lower-right corner of the rectangle, move one character farther. Why move one character farther? Remember that when you define a region, the character that the cursor is on isn't part of the region. (The character that the mark is on is part of the region.)
让我们定义一个覆盖表格第二列的矩形。
Let's define a rectangle that covers the second column of our table.
|
移至 Move to the |
|
|
|
该标记设置在要移动的矩形的左上角。 The mark is set at the upper-left corner of the rectangle to be moved. |
|
将光标移动到矩形右下角 in 后面的 Move the cursor to the space following the bottom-right corner of the
rectangle, the |
|
|
|
光标跟随矩形的右下角。 The cursor follows the bottom-right corner of the rectangle. |
现在矩形已被标记,我们要删除它然后移动它。删除矩形以便您可以在其他地方检索它的命令是Cx r k(用于 Kill-rectangle)。
Now that the rectangle is marked, we want to delete it and then move it. The command to delete a rectangle so you can retrieve it elsewhere is C-x r k (for kill-rectangle).
|
类型:Cx rk Type: C-x r k |
|
|
|
矩形被删除;它位于一个特殊的矩形终止缓冲区中。 The rectangle is deleted; it's in a special rectangle kill buffer. |
再次,当您标记矩形时,将光标放在左上角,设置标记,然后移动到矩形的右下角,再移动一个空格。 Emacs 期望矩形就是矩形。如有必要,它会用空格填充一个区域以构成右侧的直线。
Once again, when you mark a rectangle, you put the cursor on the upper-left corner, set the mark, then move to the lower-right corner of the rectangle and over one more space. Emacs expects rectangles to be rectangles. If necessary, it pads an area with spaces to make up the straight line on the right side.
您可以移动屏幕上的任何位置,并使用yank-rectangle 命令Cx r y重新插入上次删除的矩形。要将“小时”列放在表格的右侧,我们将光标移动到手机列后面。
You can move anywhere on the screen and reinsert the rectangle last killed with the yank-rectangle command, C-x r y. To put the "Hours" column on the right side of the table, we move the cursor following the cell phone column.
|
将光标放在下面 Place the cursor following |
|
|
|
将光标移动到我们要重新插入矩形的位置。 Move the cursor to where we want to reinsert the rectangle. |
Emacs 会准确地将矩形插入到您指定的位置。我们移过了手机列,然后在手机和小时列之间添加了一些空格。否则,Emacs 会毫不犹豫地将小时列插入到手机列的中间。请注意,没有与矩形的杀伤环等效的东西。您只能拉动最近的矩形。[ 4 ]
Emacs inserts the rectangle exactly where you tell it to. We moved past the cell phone column and then added some space between the cell phone and hours columns. Otherwise, Emacs would have blithely inserted the hours column into the middle of the cell phone column. Note that there's no equivalent of the kill ring for rectangles. You can yank only the most recent rectangle.[4]
杀死和拉动矩形需要练习。一旦掌握了该过程的窍门,就可以轻松编辑表格和其他与列相关的材料。
Killing and yanking rectangles requires practice. Once you get the hang of the procedure, it is an easy way to edit tables and other column-dependent material.
其他一些命令创建空白矩形。例如,假设我们想在手机和小时列之间再添加四个空格。为此,我们设置标记,移至列底部,向前移动四个空格,然后键入 Cx r o(表示 open-rectangle)。此命令插入一个空白矩形并将剩余文本推到右侧。
A few other commands create blank rectangles. For example, let's say we want to put four more spaces between the cell phone and hours columns. To do this, we set the mark, move to the bottom of the column, move forward four spaces, then type C-x r o (for open-rectangle). This command inserts a blank rectangle and pushes the remaining text to the right.
|
将光标移至 Move the cursor to the |
|
|
|
Emacs 将标记设置在矩形的左上角。 Emacs sets the mark at the upper-left corner of the rectangle. |
现在我们需要定义要插入的空间量。向下移动到矩形的底部(“Alvin”线),然后移动到6:00和之间的连字符3:00。
Now we need to define the amount of space we want to insert. Move
down to the bottom of the rectangle (the
"Alvin" line) and then move to the
hyphen between 6:00 and 3:00.
|
将光标移动到 后面 Move the cursor following |
|
|
|
矩形的右下角已定义。 The lower right corner of the rectangle is defined. |
最后,键入Cx r o将新空间添加到表中。
Finally, type C-x r o to add the new space to the table.
|
Cx型 Type C-x r o |
|
|
|
Emacs 插入一个四个空格宽的空白矩形。它将表格的其余部分移至右侧。 Emacs inserts a blank rectangle that is four spaces wide. It moves the rest of the table to the right. |
清除矩形命令擦除文本,在其位置留下一个空白矩形。这就好像你擦掉了黑板上的一栏一样。与黑板列一样,被擦除的文本列消失了,没有存储在矩形删除缓冲区中。继续我们的例子,假设在查看了时间表之后,所有相关人员都同意他们不想列出自己的手机。
The clear-rectangle command wipes out text, leaving a blank rectangle in its place. It's just as though you had erased a column on a blackboard. Like the blackboard column, the text column that is wiped out is gone, not stored in the rectangle kill buffer. To continue with our example, let's say that after reviewing the schedule, all those involved agreed that they'd rather not have their cell phones listed.
|
将光标移至 Move the cursor to the |
|
|
|
标记要清除的矩形的左上角。 The upper-left corner of the rectangle to be cleared is marked. |
|
移至最后一个电话号码后面的空格并键入:Cx rc Move to the space following the last phone number and type: C-x r c |
|
|
|
清除矩形命令删除“手机”列并在其位置留下空白。 The clear-rectangle command removes the "Cell Phone" column and leaves a blank space in its place. |
正如你所看到的,我们的桌子的间距仍然不完美;您可能想要使用删除矩形命令[ 5 ]删除第二列和第三列之间的额外空间。要删除空白而不存储它,请首先将光标移动到最长电子邮件地址后面的空格,然后按C-空格键设置标记,然后移动到要删除的框的对角并键入Cx r d。
As you can see, the spacing of our table still isn't perfect; you'd probably want to use the delete-rectangle command[5] to delete the extra space between the second and the third columns. To delete the blank space without storing it, start by moving the cursor to the space following the longest email address and press C-Space to set the mark, then move to the opposite corner of the box you want to delete and type C-x r d.
|
在标题行上,移至最长电子邮件地址后面的列,然后按C-Space On the header line, move to the column after the longest email address and press C-Space |
|
|
|
待删除矩形的左上角已被标记。 The upper-left corner of the rectangle to be deleted is marked. |
|
最后一行 6:00 之前移动几个空格并输入Cx rd Move a few spaces before 6:00 on the last line and type C-x r d |
|
|
|
delete -rectangle命令删除空白区域。 The delete-rectangle command deletes the blank space. |
如果您正在进行一些非常奇特的表格编辑,那么能够存储多个矩形会很有帮助。这样,您可以将每一列都作为一个矩形,并为每列之间放置精确的空白空间量提供一个矩形。您可以通过键入Cx rr
r将矩形存储在寄存器中,其中
r是任何字母数字字符,包括标点符号。要插入已存储的矩形,请输入Cx ri
r。寄存器在会话之间不会持续存在。
If you're doing some really fancy table editing,
being able to store several rectangles is helpful. That way, you can
have every column as a rectangle, as well as having a rectangle for
the exact amount of blank space to put between each column. You can
store rectangles in registers by typing C-x r r
r where
r is any alphanumeric character, including
punctuation. To insert a rectangle you've stored,
type C-x r i
r. Registers
don't persist between sessions.
表7-5列出了矩形 命令。
Table 7-5 lists rectangle commands.
表 7-5。矩形命令
Table 7-5. Rectangle commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CXR C-x r k |
杀死矩形 kill-rectangle |
删除一个矩形并存储它。 Delete a rectangle and store it. |
|
CXRD C-x r d |
删除矩形 delete-rectangle |
删除一个矩形并且不存储它。 Delete a rectangle and do not store it. |
|
CXR C-x r y |
拉动矩形 yank-rectangle |
插入最后被杀死的矩形。 Insert the last rectangle killed. |
|
CXRC C-x r c |
透明矩形 clear-rectangle |
使用空格将标记为矩形的区域清空并且不存储它。 Using spaces, blank out the area marked as a rectangle and do not store it. |
|
CXRO C-x r o |
开放矩形 open-rectangle |
在标记的区域中插入一个空白矩形。 Insert a blank rectangle in the area marked. |
|
CX RR C-x r r r |
复制矩形到寄存器 copy-rectangle-to-register |
复制矩形到寄存器 Copy rectangle to register |
|
CXR C-x r i r |
插入寄存器 insert-register |
从寄存器插入矩形 Insert rectangle from register |
|
(没有任何) (none) |
删除空白矩形 delete-whitespace-rectangle |
如果矩形包含初始空白,则将其删除,从而缩小矩形。 If a rectangle includes initial whitespace, deletes it, narrowing rectangle. |
|
Cx rt 字符串 输入 C-x r t string Enter |
字符串矩形 string-rectangle |
将标记矩形的内容更改为
Change contents of marked rectangle to
|
|
(没有任何) (none) |
字符串插入矩形 string-insert-rectangle |
提示输入字符串并插入矩形。 Prompts for string and inserts rectangle. |
如果您熟悉 CUA 模式,它是从 21.3.5 开始的 Emacs 的一部分,您可能知道它提供了 Windows 用户熟悉的剪切和粘贴键序列,如 Cx剪切和Cv粘贴(请参见第 13 章)。 CUA 模式第二个最常被吹捧的功能是其卓越的矩形支持。
If you are familiar with CUA mode, which is part of Emacs starting with 21.3.5, you may know that it provides cut and paste key sequences familiar to Windows users, as in C-x to cut and C-v to paste (see Chapter 13). The second most commonly touted feature of CUA mode is its superior rectangle support.
我们刚刚查看了无数的矩形命令。 CUA 的矩形支持要简单得多。通过学习一个命令,您就可以在 CUA 模式下剪切和粘贴矩形。
We've just looked at a myriad of rectangle commands. CUA's rectangle support is far simpler. By learning essentially one command, you can cut and paste rectangles in CUA mode.
不幸的是,目前 CUA 模式支持是标准的,但在 Emacs 21.3.5 上并不细致。你要么吃掉整个辣酱玉米饼馅,要么不吃。要打开它,请从选项菜单中选择 Cx/Cc/Cv 剪切和粘贴 (CUA)。如果您通常不喜欢使用 CUA 键绑定进行剪切和粘贴,则可以仅在进行矩形编辑时打开此选项。
Unfortunately at present, CUA mode support is standard but not nuanced on Emacs 21.3.5. You either take the whole enchilada or you don't. To turn it on, select C-x/C-c/C-v cut and paste (CUA) from the Options menu. If you don't generally like to use the CUA keybindings for cut and paste, you might turn this option on only when you are doing rectangle editing.
要选择矩形,请键入Shift-Enter。默认情况下,Emacs 开始以深粉色突出显示。您可以使用正常的光标移动键扩展突出显示(鼠标目前不起作用)。
To select a rectangle, type Shift-Enter. Emacs starts to highlight in a dark pink color by default. You extend the highlighting with normal cursor movement keys (the mouse does not work at present).
|
移至 Move to the |
|
|
|
矩形的左上角已被标记(Windows)。 The upper-left corner of our rectangle is marked (Windows). |
迷你缓冲区显示 CUA 模式矩形命令的数组。现在,我们只需标记矩形并暂时尝试其中一个命令。
The minibuffer displays an array of CUA mode rectangle commands. For now, we'll just mark the rectangle and experiment with one of these commands momentarily.
|
将光标移至 Alvin 电话号码中的最后一个号码。 Move the cursor to the last number in Alvin's phone number. |
|
|
|
矩形已标记 (Windows)。 The rectangle is marked (Windows). |
请注意,标记的矩形并不是严格意义上的矩形。电话号码形成一个真正的矩形,但为了创建一个包含列标题的矩形,我们需要要求 CUA 模式使用Mp(前面在迷你缓冲区中列出的命令之一)“填充”矩形。
Note that the marked rectangle isn't strictly rectangular in shape. The phone numbers form a true rectangle, but in order to create a rectangle that includes the column header, we need to ask CUA mode to "pad" the rectangle using M-p, one of the commands listed in the minibuffer earlier.
现在,我们可以分别使用Cx或Cv剪切或粘贴矩形 。这只是 CUA 模式矩形命令的体验。您可以自行探索更多内容。我们认为您应该了解此方法,作为多年来 Emacs 中键盘密集型矩形命令的替代方法。
We can now cut or paste the rectangle using C-x or C-v respectively. This is just a taste of the CUA mode rectangle commands. You can explore more of them on your own. We thought you should be aware of this method as an alternative to the more keyboard-intensive rectangle commands that have been part of Emacs for many years.
Emacs 无论如何都不是 意思是图形包,但它确实提供了一些有限的绘图功能。 Emacs 包含图片模式,允许您使用键盘字符绘制简单的图片;它还包括艺术家模式,使您可以使用鼠标快速绘图。
Emacs is not, by any means, a graphics package, but it does provide some limited drawing capabilities. Emacs includes a picture mode that allows you to draw simple pictures using keyboard characters; it also includes artist mode, which enables you to draw quickly using the mouse.
你为什么想用 Emacs 画画?嗯,Emacs 对于在邮件消息中插入快速绘图或图表非常有用,这是大多数图形包无法做到的。它还适合制作框图、时序图(针对电气工程师)、时间线和其他简单的绘图。
Why would you want to draw with Emacs? Well, Emacs is useful for inserting a quick drawing or diagram in a mail message, something that most graphics packages can't do. It's also good for making block diagrams, timing diagrams (for electrical engineers), timelines, and other simple drawings.
不要忽视这个简单的设施!我们已经看到许多论文的格式都经过精心设计,中间放置了一个简单的星条图。当然,您可以使用图形包来创建更好的绘图,但如果这不是您的专业领域,Emacs ASCII 绘图可能只是您的选择。[ 6 ]我们首先讨论图片模式,然后讨论艺术家模式。
Don't overlook this simple facility! We have seen many papers that were carefully formatted with a simple star-and-bar diagram dropped in the middle. Sure, you can use a graphics package to create a much nicer drawing, but if that's not your area of expertise, an Emacs ASCII drawing might be just the ticket.[6] We discuss picture mode first and then artist mode.
图片模式将正在编辑的区域变成一种由列和行组成的画板。例如,在图片模式下,您可以使用键盘字符创建简单的图片(如图7-3中的图片),而无需通过自动填充模式的自动换行功能“重新排列”它们。
Picture mode turns the area being edited into a kind of drawing board consisting of columns and rows. In picture mode, you can create simple pictures (such as the one in Figure 7-3) using keyboard characters without having them "rearranged" by the word-wrap capabilities of auto-fill mode, for example.
进入图片模式下,输入Mx
edit-picture。该单词
Picture出现在模式行上,后面跟着默认的绘图方向(稍后将详细介绍)。键入Cc
Cc会退出图片模式并返回到之前所处的主要模式。
To enter picture mode, type M-x
edit-picture. The word
Picture appears on the mode line, followed by the
default drawing direction (more on that shortly). Typing C-c
C-c exits
picture mode and returns you to whatever major mode you were in
before.
在图片模式下,您可以使用 八个方向中任意一个方向的任意字符。虽然您可以在八个方向上绘制,但一次只能使用一个方向;该方向称为 默认 方向。第一次进入图片模式时,默认方向是向右,也就是说,如果按四次连字符键,就会向右画一条线,如下:——。默认方向显示在模式行上,如下所示:
In picture mode, you can "draw" with any character in any of eight directions. Although you can draw in eight directions, only one direction is available at a time; this direction is referred to as the default direction. When you first enter picture mode, the default direction is right, meaning that if you press the hyphen key four times, you would draw a line to the right, as follows: ——. The default direction is displayed on the mode line, like this:
(图:右)
(Picture: right)
通过键入更改默认方向的特殊命令,您还可以沿其他七个方向进行绘制。例如,Cc
\使默认方向为“东南;”模式行将显示为(Picture:
se)。如果您朝这个方向键入四个连字符,它们看起来就像楼梯:
By typing special commands that change the default direction, you can
draw in seven other directions as well. For example, C-c
\ makes
the default direction "southeast;"
the mode line would then read (Picture:
se). If you typed four hyphens in this direction,
they would look like stair steps:
- - - -
- - - -
图 7-4说明了在图片模式下将各种方向设置为默认方向的命令。
Figure 7-4 illustrates the commands for setting various directions as the default in picture mode.
图片模式试图使这些命令易于记忆,而且效果还不错:例如,Cc ^指向上方,Cc-`可以说指向西北,等等。如果你能想出一个好的助记符来抄送。让我们知道!也许您可以将其视为“点代表羽绒”。
Picture mode tries to make these commands easy to remember, and it doesn't do too badly: for example, C-c ^ points upward, C-c-` arguably points to the northwest, and so on. If you can come up with a good mnemonic device for C-c . let us know! Maybe you can think of it as "dot for down."
设置默认方向后,重复按任意字符会沿该方向绘制一行字符。在暂存缓冲区中尝试一下,使用图中的命令更改默认方向。尝试画一个盒子。[ 7 ]
After you set a default direction, pressing any character repeatedly draws a line of characters in that direction. Give it a try in a scratch buffer, using the commands in the figure to change the default direction. Try drawing a box.[7]
|
类型:MX 图片模式 Type: M-x picture-mode |
|
|
|
将缓冲区置于图片模式,默认方向“右”。 Putting the buffer into picture mode, default direction "right." |
|
类型:标签 M-20 - Type: Tab M-20 - |
|
|
|
Emacs 向右画一条线。接下来,我们将默认方向更改为向下,并使用|对于正方形的右侧。 Emacs draws a line to the right. Next, we'll change the default direction to down, and use | for the right side of the square. |
|
类型:抄送。 M-5 | Type: C-c . M-5 | |
|
|
|
Emacs 向下画一条线。现在我们将默认方向设置为“左”,然后绘制正方形的底部。 Emacs draws a line down. Now we'll set the default direction to "left," then draw the bottom of the square. |
到现在为止,你应该已经有了一个基本的 了解图片模式可以为您做什么。它是更复杂的次要模式之一,因为它重新定义了许多主要编辑键的功能,并且有充分的理由。用于大多数 ASCII 文件的编辑技术不适用于图片。你并不是真的想插入字符;标准插入模式会阻止您有效编辑,因为您键入的任何字符都会扭曲该行的其余部分。因此,图片模式隐式更改为覆盖模式。许多其他功能都被重新定义——有些以无关紧要的方式进行,有些则以更重要的方式进行。
By now, you should have a basic understanding of what picture mode can do for you. It's one of the more complicated minor modes because it redefines what many of the major editing keys do—and with good reason. The editing techniques you use for most ASCII files just won't work well for pictures. You don't really want to insert characters; the standard insert mode would prevent you from editing effectively, because any character you type distorts the rest of the line. Therefore, picture mode implicitly changes to overwrite mode. Many other features are redefined—some in insignificant ways, others in more substantial ways.
因此,为了公正地对待图片模式,我们必须重新审视大多数基本的编辑概念。请耐心等待,如果您对图片不感兴趣,请跳过本节。让我们从头开始:基本的光标运动。
Therefore, to do justice to picture mode, we have to revisit most of the basic editing concepts. Please bear with us, or skip this section if you aren't interested in pictures. Let's start at the beginning: basic cursor motion.
图片模式使一些 基本光标命令中的小但重要的变化。有一个简单的方法来总结这些变化:在图片模式下,缓冲区变成行和列的网格。例如,考虑一下Cf在大多数其他模式中的作用:它在文件中向前移动,一次一个字符。重复键入Cf会将光标移动到左侧,然后在行尾跳转到下一行的第一个字符。图片模式中,Cf表示“向右移动”。当您在图片模式下到达行尾时,Cf 不会换行到下一行;它继续向当前行添加字符。
Picture mode makes some small but important changes in the basic cursor commands. There's an easy way to summarize these changes: in picture mode the buffer becomes a grid of rows and columns. For example, consider what C-f does in most other modes: it moves forward through the file, one character at a time. Typing C-f repeatedly moves the cursor to the left, then at the end of the line, it jumps to the first character on the next line. picture mode, C-f means "move to the right." When you reach the end of the line in picture mode, C-f doesn't wrap to the next line; it continues adding characters to the current line.
Cp和Cn分别成为垂直“向上”和“向下”命令。尝试编辑一些示例文本,移动到行尾,然后输入 Cp。通常,当您输入Cp时,光标停留在行尾;如果上一行很短,则光标向上移动时向左移动。在图片模式下, Cp和 Cn始终沿直线向上(或向下)移动。
C-p and C-n become vertical "up" and "down" commands, respectively. Try editing some sample text, moving to the end of a line, and typing C-p. Normally, as you type C-p, the cursor stays at the end of the line; if the previous line is short, the cursor moves to the left when it goes up. In picture mode, C-p and C-n always move up (or down) in a straight line.
您可以使用Cf、Cb、 Cp和Cn到达您需要去的每个地方。箭头键也可以使用,但您可能还想知道在默认方向上移动的光标移动命令,这样您也可以在速度更快时向侧面移动。Cc Cf使您沿默认方向向前移动(因此此处的“向前”可能意味着向左、向右、向上或向下,以及中间的所有方向)。Cc Cb使您沿默认方向向后移动。 (未定义相对于默认方向“向上”或“向下”移动。)
You can get to every place you need to go with C-f, C-b, C-p, and C-n. The arrow keys work too, but you may want to know the cursor movement commands for moving in the default direction as well, so you can also go sideways when it's faster. C-c C-f moves you forward in the default direction (so "forward" here could mean to the left, right, up, or down, as well as all directions in between). C-c C-b moves you backward in the default direction. (Moving "up" or "down" relative to the default direction isn't defined.)
例如,假设您绘制了如图 7-1所示的房子,并且希望将光标向下移动到屋顶的左侧。您可以通过键入Cc /将默认方向设置为“西南” 。如果光标位于屋顶左侧的顶部木瓦上,键入 Cc Cf会将您移至屋顶左侧,键入Cf会将您移至右上角木瓦,如图7-5所示。
For example, let's say you had drawn the house shown in Figure 7-1 and you wanted to move the cursor down the left side of the roof. You would set the default direction to "southwest" by typing C-c /. If the cursor were on the top shingle on the left side of the roof, typing C-c C-f would move you down the left side of the roof and typing C-f would move you to the top-right shingle, as shown in Figure 7-5.
图 7-5。使用默认方向与典型的光标移动命令
Figure 7-5. Using the default direction versus typical cursor movement commands
当你继续工作在 图片模式,你会发现更多惊喜。在图片模式下按Enter 键会将您移动到下一行的开头,而不插入空行 - 假设您可能不想更改行之间的关系。如果要插入新行,请输入Co;当前行下方出现一个空行,并且光标不移动。例如,光标最初位于第一行的 0 上。如果我们想在两者之间打开另一行,我们输入Co。
As you continue to work in picture mode, you'll find a few more surprises. Pressing Enter in picture mode moves you to the beginning of the next line, without inserting a blank line—on the assumption that you probably don't want to change the relationship between lines. If you want to insert a new line, type C-o; an empty line appears beneath the current line, and the cursor does not move. For example, the cursor is initially on the 0 in the first line. If we want to open another line between the two, we type C-o.
做起来比较困难的事情之一 图片模式是输入标准回车符,中间换行。您可以移动到一行中间的某个点,输入Ck删除右侧部分,输入 Co插入空行;键入 Enter移动到该空行的开头,然后键入Cy将该行的右侧部分拉回。或者您可以使用 分行命令(CMo),然后删除新行开头的空格。
One of the more difficult things to do in picture mode is to type a standard carriage return that breaks a line in the middle. You can move to a point in the middle of a line, type C-k to kill the right-hand portion, type C-o to insert a blank line; type Enter to move to the beginning of this blank line, and type C-y to yank the right-hand part of the line back. Or you can use the split-line command (C-M-o), and then delete the blank space at the beginning of the new line.
删除并不完全是 也一样。在图片模式下,Cc Cd是您习惯的删除字符命令:它删除光标下的字符并将该行的其余部分向左移动。未经修饰的 Cd会删除光标下的字符,并将其替换为空格。Del删除光标左侧的字符,并将其替换为空格。
Deletion isn't quite the same, either. In picture mode C-c C-d is the delete character command that you're used to: it deletes the character under the cursor and moves the rest of the line to the left. An unadorned C-d deletes the character under the cursor, replacing it with a space. Del deletes the character to the left of the cursor, replacing it with a space.
表 7-6将图片模式命令与其正常文本模式行为进行了对比。
Table 7-6 contrasts the picture mode commands with their normal text mode behavior.
表 7-6。图片模式与文本模式
Table 7-6. Picture mode v. text mode
|
击键 Keystrokes |
在文本模式下 In text mode |
在图片模式下 In picture mode |
图片模式替代 Picture mode alternative |
|---|---|---|---|
|
进入 Enter |
插入一个空行。 Insert a blank line. |
将光标移动到下一行的开头。 Move the cursor to the beginning of the next line. |
Co插入空行。 C-o inserts blank lines. |
|
光盘 C-d |
删除该字符并将文本向左移动。 Delete the character and move the text to left. |
将角色替换为空格并且不要移动。 Replace the character with Space and don't move. |
Cc Cd类似于文本模式下的Cd 。 C-c C-d is like C-d in text mode. |
|
空间 Space |
将文本向右移动并插入一个空格。 Move the text to the right and insert a space. |
将光标向右移动并删除空格上的任何字符。 Move the cursor to the right and delete any character you space over. |
没有任何;返回文本模式以插入空格。 None; go back to text mode to insert blank spaces. |
|
肌酸 C-k |
擦除当前行的文本;按Ck两次可删除一行。 Erase the text on the current line; pressing C-k twice deletes a line. |
擦除当前行的文本;它不会删除该行。 Erase the text on the current line; it doesn't delete the line. |
要删除一行,请返回文本模式或使用delete-rectangle。 To delete a line, go back to text mode or use delete-rectangle. |
|
标签 Tab |
插入制表符并将剩余文本移至右侧。 Insert tabs and move the remaining text to the right. |
在屏幕上移动光标,但不影响下面的文本。 Move the cursor across the screen but don't affect the underlying text. |
要插入一个制表符的空间,请返回文本模式。 To insert a tab's worth of space, go back to text mode. |
|
中文 C-n |
移至下一行。 Move to the next line. |
向下移动,保持在同一列。 Move down, staying in the same column. |
(没有任何) (none) |
|
CP C-p |
移至上一行。 Move to the previous line. |
向上移动,保持在同一列。 Move up, staying in the same column. |
(没有任何) (none) |
|
CF C-f |
在文件中向前移动一个字符。 Move one character forward in the file. |
向右移动一个字符。 Move one character to the right. |
(没有任何) (none) |
|
镉 C-b |
在文件中向后移动一个字符。 Move one character backward in the file. |
向左移动一个字符;停在该行的开头。 Move one character to the left; stop at the beginning of the line. |
(没有任何) (none) |
如果你想插入一块空白区域, 您可以使用矩形命令,例如 open-rectangle。有关详细信息,请参阅本章前面对此命令的讨论。另外,如果您想在行尾插入空格,可以使用 Cf。
If you want to insert a block of blank space, you can use a rectangle command such as open-rectangle. See the discussion of this command earlier in this chapter for more information. Also, if you want to insert blank space at the end of a line, you can use C-f.
要执行某些任务,您可能会发现暂时切换回您习惯的模式会更容易。Cc Cc可让您返回到进入图片模式之前所处的模式。进行必要的更改,然后通过键入 Mx picture-mode再次进入图片模式。
To perform some tasks, you may find it easier to switch back temporarily to the mode you're used to. C-c C-c moves you back to the mode you were in before you entered picture mode. Make any necessary changes, then enter picture mode again by typing M-x picture-mode.
如果您想移动已绘制的内容,最简单的方法是使用矩形,如本章前面所述。
If you want to move something you've drawn, the easiest way is to use rectangles, as described earlier in this chapter.
选项卡也有所不同 图片模式。默认情况下,如果以下字符单独出现在一行上,图片模式会将其解释为制表位:感叹号 (!)、连字符 (-) 和波形符 (~)。如果这些字符出现在一行上并且用户在下一行上按制表符,则假定这些字符表示制表位。您可以通过将变量picture-tab-chars设置为其他字符来更改此行为。如果字符与普通文本一起出现,则它们不会被解释为制表位。要将这些字符用作制表位,请按 Esc-Tab(用于图片制表符搜索)。
Tabs are also different in picture mode. By default, picture mode interprets the following characters as tab stops if they appear by themselves on a line: exclamation point (!), hyphen (-) and tilde (~). If these characters appear on a line and the user presses tab on the next line, these characters are presumed to denote tab stops. You can change this behavior by setting the variable picture-tab-chars to other characters. If the characters appear with normal text, they are not interpreted as tab stops. To use these characters as tab stops, press Esc-Tab (for picture-tab-search).
表 7-7总结了在图片模式下进行编辑的命令。
Table 7-7 summarizes the commands for editing in picture mode.
表 7-7。图像模式命令
Table 7-7. Picture mode commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
(没有任何) (none) |
图片模式或编辑图片 picture-modeoredit-picture |
进入图片模式。 Enter picture mode. |
|
抄送抄送 C-c C-c |
图像模式退出 picture-mode-exit |
退出图片模式并返回之前的模式。 Exit picture mode and return to the previous mode. |
|
抄送^ C-c ^ |
图片向上移动 picture-movement-up |
将默认绘图方向设置为向上。 Set the default drawing direction to up. |
|
抄送。 C-c . |
图片向下移动 picture-movement-down |
将默认绘图方向设置为向下。 Set the default drawing direction to down. |
|
抄送 > C-c > |
图片向右移动 picture-movement-right |
将默认绘图方向设置为向右。 Set the default drawing direction to right. |
|
抄送 < C-c < |
图片向左移动 picture-movement-left |
将默认绘图方向设置为左侧。 Set the default drawing direction to left. |
|
抄送` C-c ` |
图片运动西北 picture-movement-nw |
将默认绘图方向设置为西北。 Set the default drawing direction to northwest. |
|
抄送` C-c ` |
图片运动ne picture-movement-ne |
将默认绘图方向设置为东北。 Set the default drawing direction to northeast. |
|
抄送 / C-c / |
图片运动SW picture-movement-sw |
将默认绘图方向设置为西南。 Set the default drawing direction to southwest. |
|
抄送\ C-c \ |
图像运动SE picture-movement-se |
将默认绘图方向设置为东南。 Set the default drawing direction to southeast. |
|
抄送 抄送 C-c C-f |
图像运动 picture-motion |
沿默认绘图方向向前移动光标。 Move the cursor forward in the default drawing direction. |
|
抄送 抄送 C-c C-b |
图像运动反转 picture-motion-reverse |
沿默认绘图方向向后移动光标。 Move the cursor backward in the default drawing direction. |
|
CF C-f |
图片前进栏 picture-forward-column |
将光标移至右侧一个字符。 Move the cursor to the right one character. |
|
镉 C-b |
图片后退栏 picture-backward-column |
将光标向左移动一个字符。 Move the cursor to the left one character. |
|
中文 C-n |
图片下移 picture-move-down |
将光标向下移动一个字符。 Move the cursor down one character. |
|
CP C-p |
图片上移 picture-move-up |
将光标向上移动一个字符。 Move the cursor up one character. |
|
光盘 C-d |
图片清晰栏 picture-clear-column |
清空光标下的字符;不会将剩余文本向左移动。 Blank out the character under the cursor; doesn't move remaining text to the left. |
|
镉镉 C-c C-d |
删除字符 delete-char |
删除光标下的字符并将剩余文本向左移动。 Delete the character under the cursor and move the remaining text to the left. |
|
肌酸 C-k |
图片清晰线 picture-clear-line |
删除当前行的文本;如果使用两次,该行不会被删除。 Delete the text on the current line; the line is not deleted if used twice. |
|
钴 C-o |
图片开线 picture-open-line |
插入一个空行。 Insert a blank line. |
|
抄送CW
C-c C-w
|
图片清晰的矩形注册 picture-clear-rectangle-to-register |
清除矩形并将其保存在寄存器中
Clear the rectangle and save it in register
|
|
铜CCCW
C-u C-c C-w
|
图片清晰的矩形注册 picture-clear-rectangle-to-register |
删除矩形并将其保存在寄存器中
Delete the rectangle and save it in register
|
|
抄送Cx
C-c C-x
|
图片从寄存器中拉出矩形 picture-yank-rectangle-from-register |
将寄存器中保存的矩形插入 Insert the rectangle saved in register |
|
CC铬 C-c C-r |
图片绘制矩形 picture-draw-rectangle |
围绕当前区域绘制一个矩形。 Draw a rectangle around current region. |
|
抄送CY C-c C-y |
图片拉动矩形 picture-yank-rectangle |
粘贴矩形。 Paste rectangle. |
|
抄送CK C-c C-k |
图片清晰的矩形 picture-clear-rectangle |
擦除矩形。 Erase rectangle. |
|
抄送选项卡 C-c Tab |
图片集制表位 picture-set-tab-stops |
设置仅适用于图片模式的制表位(!、- 和 ~ 默认表示制表位)。 Set tab stops applicable only in picture mode (!, -, and ~ denote tab stops by default). |
|
M-标签 M-Tab |
图片标签搜索 picture-tab-search |
移至下一个图片模式选项卡。 Move to the next picture mode tab. |
如果我们不这样做,那就是失职了 向您介绍艺术家模式,这是一种使用鼠标创建 ASCII 艺术作品的简单方法。 (您也可以使用键盘命令,但相信我们 - 您不会想要的。)
We would be remiss if we didn't introduce you to artist mode, an easy way to create ASCII art using the mouse. (You can also use keyboard commands, but trust us—you won't want to.)
艺术家模式是与图片模式相关的次要模式,因此您可以将它们一起使用。例如,您可以使用艺术家模式进行绘图,然后在图片模式下编辑图片。或者您可以选择单独使用艺术家模式进行创作。
Artist mode is a minor mode related to picture mode, so you use them together. For example, you might draw using artist mode, then edit the picture in picture mode. Or you might choose to use artist mode alone for your creations.
我们将带您体验艺术家模式;您可以在业余时间完善您的技能。当您启动艺术家模式时,图片模式会自动启动。
We're going to give you a taste of artist mode; you can perfect your skills in your spare time. When you start artist mode, picture mode starts automatically.
|
类型:MX 艺术家模式 Type: M-x artist-mode |
|
|
|
艺术家出现在模式行上,图片也是如此。 Artist appears on the mode line, as does Picture. |
当您启动艺术家模式时,默认选择钢笔画。
When you start artist mode, pen drawing is selected by default.
|
按住鼠标左键并四处移动以进行涂鸦。 Hold down the left mouse button and move around to scribble. |
|
|
|
随意乱写的。 A random scribble. |
使用笔,您可以自由绘画。按住鼠标中键,将出现一个菜单,其中包含“绘图”、“编辑”和“设置”子菜单。绘图菜单提供了多种形状可供选择。现在我们已经涂鸦了,让我们使用喷雾罐来创作一些涂鸦。
With the pen, you can draw freestyle. Hold down the middle mouse button and a menu appears, with Drawing, Edit, and Settings submenus. The Drawing menu offers a variety of shapes from which to choose. Now that we've scribbled, let's create some graffiti using the spray can.
|
从“绘图”菜单中选择“喷雾罐”,然后按住鼠标左键并移动鼠标来喷射屏幕。 Select Spray Can from the Drawing menu, then spray the screen by holding down the left mouse button and moving the mouse. |
|
|
|
随机喷雾。 A random spray. |
我们不会深入探讨艺术家模式,但我们想让您了解基本的绘图选择。您可以绘制矩形(我们个人最喜欢的)、椭圆形、直线(力求笔直)和折线(力求多边形)。图 7-5显示了形状的代表性示例。通过练习,您可以使用鼠标或使用标准图片模式命令创建复杂的绘图并对其进行编辑。
We aren't going to go deep into artist mode, but we would like to give you a flavor of the basic drawing choices. You can draw rectangles (our personal favorite), ellipses, lines (which strive to be straight), and poly-lines (which strive to be polygon-angular). Figure 7-5 shows a representative sample of shapes. With practice, you can create complex drawings and edit them, either using the mouse or using standard picture mode commands.
对于矩形、直线和椭圆形,按住鼠标左键并将它们拉至您喜欢的大小,如果是直线,则将其拉至您喜欢的角度。 (椭圆是由直线组成的,所以发挥你的想象力;这毕竟是 ASCII 艺术。)对于多段线,按住鼠标左键绘制一条线,然后松开。将鼠标从该线移至多边形的下一个角并单击。 Emacs 绘制一条连接两点的线。多段线允许您快速创建多边形。
For rectangles, lines, and ellipses, hold down the left mouse and pull them to the size and, in the case of lines, angle you prefer. (Ellipses are made of straight lines, so use your imagination; this is ASCII art after all.) For poly-lines, draw a line by holding down the left mouse button, then release it. Move the mouse away from that line to the next corner of the polygon and click. Emacs draws a line connecting the two points. Poly-lines allow you to create polygons quickly.
表 7-8提供了艺术家命令的概述。艺术家可以很好地使用鼠标和中键鼠标菜单;如果您不喜欢鼠标,您会更喜欢图片模式。
Table 7-8 provides an overview of artist commands. Artist works very well with the mouse and the middle-button mouse menu; if you're mouse-averse, you'll prefer picture mode.
表 7-8。艺术家模式命令
Table 7-8. Artist mode commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
(没有任何) (none) |
艺术家模式 artist-mode |
进入艺术家模式。 Enter artist mode. |
|
抄送抄送 C-c C-c |
艺术家模式关闭 artist-mode-off |
退出艺术家模式。 Exit artist mode. |
|
CF C-f |
艺术家转发字符 artist-forward-char |
向右移动一个字符(在行尾,继续向当前行添加字符)。 Move to the right one character (at end of line, keep adding characters to current line). |
|
镉 C-b |
艺术家向后字符 artist-backward-char |
向左移动一个字符(在行首,不执行任何操作)。 Move to the left one character (at beginning of line, does nothing). |
|
中文 C-n |
下一个艺术家 artist-next-line |
向下移动一列(在缓冲区末尾,继续向缓冲区添加行)。 Move down a column (at end of buffer, keep adding lines to the buffer). |
|
CP C-p |
艺术家上一行 artist-previous-line |
向上移动一列(缓冲区的第一行移动到文件中的第一个位置,然后不执行任何操作)。 Move up a column (at first line of buffer moves to first position in file, then does nothing). |
|
Cc Ca Co 或 Mouse-2 C-c C-a C-o or Mouse-2 |
艺术家选择操作 artist-select-operation |
选择一个操作(按 Tab 键查看列表)。 Select an operation (press Tab to see a list). |
|
抄送Ca f` 艺术家菜单 → 编辑 → 洪水填充 C-c C-a f` Artist menu → Edit → Flood-fill |
艺术家选择操作洪水填充 artist-select-op-flood-fill |
选择洪水填充作为操作。 Select flood fill as the operation. |
|
抄送 Ca Ck 艺术家菜单 → 编辑 → 剪切 C-c C-a C-k Artist menu → Edit → Cut |
艺术家选择操作剪切矩形 artist-select-op-cut-rectangle |
围绕一个区域画一个矩形,然后剪切。 Draw a rectangle around an area, then cut. |
|
Cc Ca Mw 艺术家菜单 → 编辑 → 复制 C-c C-a M-w Artist menu → Edit → Copy |
艺术家选择操作复制矩形 artist-select-op-copy-rectangle |
围绕一个区域绘制一个矩形,然后复制。 Draw a rectangle around an area, then copy. |
|
Cc Ca Cy 艺术家菜单 → 编辑 → 粘贴 C-c C-a C-y Artist menu → Edit → Paste |
艺术家选择操作粘贴 artist-select-op-paste |
将复制的内容粘贴到单击鼠标的任意位置。 Paste what you copied wherever you click the mouse. |
|
Cc Ca v 艺术家菜单 → 绘图 → 蒸发 C-c C-a v Artist menu → Drawing → Vaporize |
艺术家选择操作蒸发线 artist-select-op-vaporize-line |
擦除您选择的行(文字行;不是文件中的行)。 Erase a line you select (literal line; not a line in the file). |
|
抄送 Ca Cd 艺术家菜单 → 绘图 → 擦除 C-c C-a C-d Artist menu → Drawing → Erase |
艺术家选择操作擦除字符 artist-select-op-erase-char |
设置操作为擦除(使用鼠标作为橡皮擦)。 Set operation to erase (use the mouse as your eraser). |
|
Cc Ca S 艺术家菜单 → 绘图 → 喷雾罐 C-c C-a S Artist menu → Drawing → Spray-can |
艺术家选择喷雾罐 artist-select-op-spray-can |
将操作设置为喷雾罐。 Set operation to spray can. |
|
Cc Ca e 艺术家菜单 → 绘图 → 椭圆 C-c C-a e Artist menu → Drawing → Ellipse |
艺术家选择椭圆 artist-select-op-ellipse |
绘制椭圆。 Draw ellipses. |
|
Cc Cap Artist 菜单 → 绘图 → 折线 C-c C-a p Artist menu → Drawing → Poly-line |
艺术家选择 op 多线 artist-select-op-poly-line |
绘制多段线 Draws poly-lines |
|
Cc Car Artist 菜单 → 绘图 → 矩形 C-c C-a r Artist menu → Drawing → Rectangle |
艺术家选择矩形 artist-select-op-rectangle |
绘制矩形。 Draw rectangles. |
|
抄送Ca l 艺术家菜单 → 绘图 → 线条 C-c C-a l Artist menu → Drawing → Line |
艺术家选择操作线 artist-select-op-line |
画线。 Draw lines. |
|
Cc Ca Cr 艺术家菜单 → 设置 → 橡皮筋 C-c C-a C-r Artist menu → Settings → Rubber banding |
艺术家切换橡皮筋 artist-toggle-rubber-banding |
如果打开(默认),则在拉伸时显示形状;如果不是,标记终点。 If on (the default), show shape while stretching; if not, mark end-points. |
|
Cc Ca Cl 艺术家菜单 → 设置 → 设置线条 C-c C-a C-l Artist menu → Settings → Set Line |
艺术家选择行字符 artist-select-line-char |
选择绘制线条时要使用的字符(- 是默认值)。 Select character to use when drawing lines (- is the default). |
|
Cc Ca Cf 艺术家菜单 → 设置 → 设置填充 C-c C-a C-f Artist menu → Settings → Set Fill |
艺术家选择填充字符 artist-select-fill-char |
选择用于填充形状的字符(默认为空格)。 Select character to fill shapes with (Space is the default). |
艺术家模式表示您在绘图时无法更改为其他形状。退出艺术家模式,然后重新进入。在绘制任何内容之前,单击鼠标中键显示弹出菜单,然后从“绘图”菜单中选择所需的形状。
Artist mode says you can't change to another shape while drawing. Exit artist mode and then reenter. Before drawing anything, click the mouse's middle button to display the pop-up menu and select the desired shape from the Drawing menu.
[ 6 ]许多在线小组致力于 ASCII 艺术。当然,所有此类艺术作品都要求您使用等宽字体才能正确观看。alt.ascii.art等新闻组和 Ascii Art Dictionary ( http://www.ascii-art.de/ )等网站提供了很好的介绍。
[6] A number of online groups are dedicated to ASCII art. Of course, all such art requires that you use a monospace font for proper viewing. Newsgroups such as alt.ascii.art and web sites such as the Ascii Art Dictionary (http://www.ascii-art.de/) provide a good introduction.
[ 7 ]其他命令可以更快地完成此任务,但为了一个简单的示例,请耐心等待。例如,这个小练习可以通过在艺术家模式下单击鼠标拖动来完成。图片模式还提供了绘制矩形的快速命令Cc Cr。
[7] Other commands can accomplish this task more quickly, but bear with us for the sake of a simple example. For example, this little exercise could be accomplished with a single mouse drag in artist mode. Picture mode also offers a quick command for drawing a rectangle, C-c C-r.
确实,许多使用 Emacs 的人都是开发人员,他们编写代码、调整代码、重新编译代码,并且通常只是享受令人惊叹的可扩展工作环境的服务。包括开发人员在内的各种人都需要生成用于出版的文本,无论是内部发布、在线发布还是书籍格式。本章介绍 Emacs 提供的标记语言支持,这是一个与信息发布者和开发人员都相关的主题,因为越来越多的开发工作使用可扩展语言的变体 标记语言,XML。
It's true that many of the people who use Emacs are developers, writing code, tweaking it, recompiling it, and just generally enjoying the services of an amazingly extensible work environment. A variety of people, including developers, need to produce text for publication, whether internally, online, or in book format. This chapter describes the markup language support that Emacs offers, a topic relevant to both information publishers and developers, as more and more development work uses variants of the Extensible Markup Language, XML.
如今,选择生成文档的格式并不是那么简单,尤其是在您避开 Microsoft Word 的情况下。有些人编写 HTML,Emacs 为此提供了一些选项。 HTML 使您可以对格式进行一定程度的控制,但在不同浏览器上的显示效果有所不同。的 当然,它作为网络的通用语言很重要。
Choosing a format for producing documents isn't all that straightforward these days, especially if you eschew Microsoft Word. Some people write HTML, and Emacs offers a few options for this. HTML gives you some control over formatting but displays differently on various browsers. Of course, it is important as the lingua franca of the Web.
其他文本发布选项 包括 TEX 系列。 TEX(发音为“tek”)是 Donald Knuth 开发的用于生成书籍的格式化程序。 LATEX(发音为“lay-tek”)是由 Leslie Lamport 创建的一组 TEX 命令。使用 TEX 和 LATEX,您可以生成格式非常精确的文本,包括方程、有趣的字体、图形、页眉和页脚等。无论是使用过滤器还是程序本身的功能,您都可以以各种格式发布 TEX 文档。
Other text publishing options include the TEX family. TEX (pronounced "tek") is a formatter that was developed by Donald Knuth for generating books. LATEX (pronounced "lay-tek") is a set of TEX commands created by Leslie Lamport. With TEX and LATEX , you can produce very precisely formatted text with equations, interesting fonts, graphics, headers and footers, and the like. Whether using filters or features of the program itself, you can publish TEX documents in a variety of formats.
发布文本以及编程的另一个选择是 XML。 XML,当与 文档类型定义 (DTD) 或架构使您能够编写一次文本并以各种格式发布。可扩展样式语言(XSL)在这方面也很重要。由于标准仍在定义中,参与文档制作的组织可能会选择已建立的 XML 方言(例如 DocBook)作为其发布格式。 XML 此时对格式的控制不太精确,但最大限度地提高了灵活性。
Another option for publishing text—as well as programming—is XML. XML, when combined with a Document Type Definition (DTD) or schema, enables you to write text once and publish it in a variety of formats. Extensible Style Language (XSL) is also important in this regard. Because the standards are still being defined, organizations involved in document production may choose an established XML dialect, such as DocBook, as their publication format. XML at this point provides less precise control over format, but maximizes flexibility.
XML 连接了编程和出版世界,您使用 XML 所做的事情将部分决定您使用什么工具以及需要什么支持。我们讨论了在 Emacs 中编写 XML 的一些选项,包括 psgml 模式和 Jim Clark 的 nxml 模式,该模式使用 Relax NG 模式而不是 DTD 进行验证。
XML bridges the programming and publishing worlds, and what you do with XML will in part determine what tools you use and what support you need. We discuss a few options for writing XML in Emacs, including psgml mode and Jim Clark's nxml mode, which uses Relax NG schemas rather than DTDs for validation.
一些文字处理器和其他工具集成了格式化和编辑功能。这些工具通常称为 WYSIWYG(所见即所得) 工具。与所见即所得工具相比,使用 Emacs 有何优势?好吧,无论您是编写 LATEX、XML 还是 HTML,如果您使用 Emacs,您都可以非常清楚文件中的内容及其结构。将 Microsoft Word 文件另存为 HTML,然后在 Emacs 中打开生成的文件。 Word 使用非严格要求的附加标签和格式使文件变得臃肿。就输出而言,您在查看页面时在脑海中想象的精简且简单的代码绝对不是您所得到的,这是使用 Word 等所见即所得工具创建标记文件的讽刺结果。如果您已经读到这里,很可能您已经计划使用 Emacs,因此我们不会详细说明这一点。
Some word processors and other tools integrate formatting and editing. These tools are often called WYSIWYG (what you see is what you get) tools. What's the advantage of using Emacs versus a WYSIWYG tool? Well, whether you're writing LATEX, XML, or HTML, you can be crystal clear about what's in the file and how it's structured if you use Emacs. Save a Microsoft Word file as HTML and then open the resulting file in Emacs. Word bloats the file with additional tags and formatting that is not strictly required. In terms of output, the streamlined and straightforward code you picture in your mind's eye when viewing a page is definitely not what you get, an ironic consequence of using a WYSIWYG tool like Word to create markup files. Chances are, if you've read this far, you're planning to use Emacs anyway, so we won't belabor the point.
在本章中,我们讨论这些标记模式:
In this chapter, we talk about these markup modes:
对于编写 HTML,讨论了 Emacs HTML 模式(SGML 模式的子集)和附加 HTML 帮助程序模式。
For writing HTML, Emacs HTML mode (a subset of SGML mode) and the add-on HTML helper mode are discussed.
对于编写XML,简要介绍了Emacs SGML 模式以及附加模式psgml 模式和nxml 模式。
For writing XML, Emacs SGML mode and the add-on modes psgml mode and nxml mode are described in brief.
为了编写 LATEX 文档,讨论了 Emacs LaTeX 模式。
For writing LATEX documents, Emacs LaTeX mode is discussed.
这些主要模式可帮助您将格式化命令或标记插入文本中。虽然 Emacs 提供的帮助量各不相同,但使用为您的文本格式化程序设计的模式将简化您的工作。
These major modes help you insert formatting commands, or markup, into your text. While the amount of help that Emacs offers varies, using the mode designed for your text formatter will streamline your work.
此时我们必须插入一个警告。我们对本章中描述的标记模式进行了简单的介绍。我们在这里所说的内容将帮助您入门,但仅此而已。整本书都可以并且已经写成关于如何使用这里描述的每种标记工具。现在,我们来讨论一些在所有模式中都很重要的功能:注释处理和字体锁定模式。
At this point we must insert a caveat. We provide a barebones introduction to the markup modes described in this chapter. What we say here will get you started, but not much more than that. Entire books could be and have been written about using each of the markup tools described here. Now that that's out of the way, let's talk about a few features that are important in all the modes: comment handling and font-lock mode.
本章描述的所有模式共享一个 我们将在第 9 章讨论 Java 模式和 Lisp 模式等编程语言模式 。所有这些模式都理解注释并使用单个命令M-;(对于 indent-for-comment)插入适当的注释语法。表 8-1列出了本章中工具的注释语法。
All the modes described in this chapter share a feature with the programming language modes such as Java mode and Lisp mode, which we discuss in Chapter 9. All these modes understand comments and use a single command, M-; (for indent-for-comment) to insert the appropriate comment syntax. Table 8-1 lists the comment syntax for the tools in this chapter.
表 8-1。标记模式下的注释
Table 8-1. Comments in markup modes
讨论字体锁定模式 主要在第9章;它是为代码着色而设计的,以使其更易于阅读。但事实是它在其他模式下也能很好地工作,比如缓冲区列表(第 4 章)、Dired(第 5 章)以及本章中描述的所有标记模式。
Font-lock mode is discussed primarily in Chapter 9; it's designed for coloring code to make it easier to read. But the fact is that it works well in other modes too, like the Buffer List (Chapter 4), Dired (Chapter 5), and in all the markup modes described in this chapter.
要打开字体锁定模式,请从“选项”菜单中选择“语法突出显示”。如果您决定要为每个会话打开它,请从“选项”菜单中选择“保存选项”,Emacs 将写入您的 .emacs文件。
To turn on font lock mode, choose Syntax Highlighting from the Options menu. If you decide you want to turn it on for every session, select Save Options from the Options menu and Emacs writes your .emacs file.
有关字体锁定模式的更多详细信息,请参阅第 9 章。
For more details on font-lock mode, see Chapter 9.
毫无疑问,最常见的是 如今使用的标记语言是超文本标记语言(HTML),用于创建网页。 HTML 由带有定义文本特征的标签的文本组成。 HTML 并不难编写,您可以使用 Emacs 或任何其他编辑器来编写标签和文本。 HTML 标签通常如下所示:
Without doubt, the most commonly used markup language today is hypertext markup language (HTML), used for creating web pages. HTML consists of text with tags that define characteristics about the text. HTML is not hard to write, and you could use Emacs or any other editor to write the tags and the text. An HTML tag generally looks like this:
<tagname>被标记的文本</tagname>
<tagname>text being tagged</tagname>
为了您的方便,有多种模式 可用于在 Emacs 中编写 HTML,包括 HTML 模式、HTML helper 模式、html 菜单以及包括 sgml 模式和 psgml 模式在内的各种 SGML [ 1 ]工具。在这些工具中,我们选择描述 HTML 模式(GNU Emacs 中包含的 sgml 模式的一种变体)和 HTML 帮助器模式(一种流行的附加组件)。如果您正在编写 XHTML(可以验证的更严格的 HTML 版本),则应该考虑本节中简要描述的 XHTML 模式,或本章稍后的 XML 部分中介绍的 psgml 模式。
For your convenience, several modes are available for writing HTML in Emacs, including HTML mode, HTML helper mode, html menus, and a variety of SGML[1] tools including sgml mode and psgml mode. Of these tools, we've chosen to describe HTML mode, a variant of sgml mode, which is included in GNU Emacs, and HTML helper mode, which is a popular add-on. If you are writing XHTML, a stricter version of HTML that can be validated, you should consider XHTML mode, described briefly in this section, or psgml mode, covered later in the XML section of this chapter.
认真的 Web 开发人员可能希望研究一些正在进行的前沿开发,以使 Emacs 更加强大。查看 HTMLModeDeluxe ( http://www.emacswiki.org/cgi-bin/wiki/HtmlModeDeluxe ) 以及 Darren Brierton 的 Emacs WebDev 环境 ( http://www.dzr-web.com/people/darren/projects/emacs-webdev)。这两个工具都支持 mmm 模式(其中 mmm 代表“多种主要模式”)。使用此功能,光标可以根据您正在编辑的页面部分更改主要模式。当您编辑脚本时,模式会自动更改以支持该类型的创作。两者都是构建复杂网页的优秀工具。
Serious web developers may want to investigate some of the cutting edge development going on to make Emacs even more powerful. Check out HTMLModeDeluxe (http://www.emacswiki.org/cgi-bin/wiki/HtmlModeDeluxe) and the Emacs WebDev Environment by Darren Brierton (http://www.dzr-web.com/people/darren/projects/emacs-webdev). Both of these tools support mmm mode (where mmm stands for "multiple major modes"). Using this feature, the cursor changes major mode depending on the section of the page you are editing. When you edit a script, the mode changes automatically to support that type of authoring. Both are excellent tools for building complex web pages.
在下面的部分中,我们不会教您编写 HTML。 (有关编写 HTML 的更多信息,请参阅Chuck Musciano 和 Bill Kennedy、O'Reilly 编写的《HTML 和 XHTML:权威指南》)相反,我们将教您使用 HTML 模式和 HTML 帮助程序模式的基础知识来帮助您创建HTML 文档。
In the following sections, we are not going to teach you to write HTML. (For more information on writing HTML, see HTML and XHTML: The Definitive Guide by Chuck Musciano and Bill Kennedy, O'Reilly) Rather, we're going to teach you the rudiments of using HTML mode and HTML helper mode to help you create HTML documents.
要启动 HTML 模式,请输入Mx html-mode(或简单地
打开 HTML 文件)。大多数作者在编写 HTML 时都使用标准模板。您可能已经拥有一个。如果您不这样做,HTML 模式很乐意为您提供一个。只需键入Cc Ct(对于sgml-tag)或从 SGML 菜单中选择“插入标签”即可开始。如果您输入<html>表示 HTML 文档开始的标记,Emacs 会在您的缓冲区中插入一个基本模板。
To start HTML mode, type M-x
html-mode (or simply
open an HTML
file). Most authors use a standard template when they write HTML. You
may already have one. If you don't, HTML mode is
happy to supply one for you. Simply start by typing C-c C-t (for sgml-tag) or by selecting Insert Tag from the
SGML menu. If you enter the <html> tag that
signifies the start of an HTML document, Emacs inserts a basic
template in your buffer.
请注意,Emacs 会自动 创建一个与您输入的标题相同的第一级标题。它还插入一个超链接,以便读者可以向您发送电子邮件。根据您的垃圾邮件容忍度,您可能需要删除该行。此外,Emacs 只是猜测您的姓名和电子邮件地址。您可以通过向 .emacs文件添加两行来显式设置这些内容。将狄更斯先生的信息更改为适合您的设置。
Note that Emacs automatically creates a first-level header that is equal to the title you entered. It also inserts a hyperlink so that readers can email you. Depending on your spam tolerance, you may want to delete that line. Also, Emacs is just guessing at your name and email address. You can set these explicitly by adding two lines to your .emacs file. Change Mr. Dickens' information to settings appropriate for you.
(setq 用户邮件地址“cdickens@great-beyond.com”) (setq 用户全名“查尔斯·狄更斯”)
(setq user-mail-address "cdickens@great-beyond.com") (setq user-full-name "Charles Dickens")
您可以通过多种方式来实现 HTML 模式。您可以了解各种标签的键绑定,或者您可以简单地使用sgml-tag命令来完成所有操作。这取决于您想要学习多少绑定。混合方法可能是最好的,您可以学习最常见标签的击键,并使用sgml-tag来学习不太常见的标签。
You could approach HTML mode in a couple of ways. You could learn the key bindings for various tags, or you could simply use the sgml-tag command for everything. It depends how many bindings you want to learn. A mixed approach may be best, where you learn keystrokes for the most common tags and use sgml-tag for less common tags.
键绑定是
HTML 模式下直观。与大多数专业编辑模式一样,许多功能都与Cc C-
something绑定。我们已经看到Cc Ct
来插入标签。如果您发现要前进到下一个标签,您输入Cc Cf,要返回到上一个标签,您输入Cc Cb,您不会感到太惊讶。要插入
<href>标签,请键入Cc Ch。你明白我们的意思了。
Key bindings are
intuitive in HTML mode. Like most
specialized editing modes, many functions are bound to C-c C-
something.
We've seen C-c C-t
to insert a tag. You won't be too surprised to find
that to move forward to the next tag you type C-c C-f and to move back to the previous tag
you type C-c C-b. To insert an
<href> tag, type C-c
C-h. You see what we mean.
HTML 模式专为
编写 HTML,而不是 XHTML。 XHTML 更严格,要求所有标签都有结束标签。通用<p>标签就是一个突出的例子。 HTML 作者绝不会使用 XHTML 所需的结束标记
</p>。即使给出通常会插入标签对的<p>命令(例如sgml-tag ) , HTML 模式也会插入一个单独的标签。如果你想编写XHTML,请使用XHTML模式。如果您的文件包含对 XHTML 文档类型定义的引用,Emacs 会自行启动此模式。除了完成标签之外,XHTML 模式与此处描述的 HTML 模式非常相似。[ 2 ]
HTML mode is designed for
writing
HTML, not XHTML. XHTML is stricter, requiring all tags to have a
closing tag. The common <p> tag is a salient
example. HTML authors would never use the closing tag
</p> that XHTML requires. HTML mode inserts
a lone <p> tag even when given a command,
such as sgml-tag, that normally
inserts a tag pair. If you want to write XHTML, use XHTML mode
instead. Emacs starts this mode itself if your file contains a
reference to an XHTML document type definition. Other than completion
of tags, XHTML mode is very similar to HTML mode described
here.[2]
能够隐藏标签是一个 有用的功能。要隐藏 HTML 标签,请输入 Cc Tab;使用相同的命令再次显示标签。假设我们已将一些 dickens文件插入到 我们刚刚使用的dickens.html文件中。
Being able to hide the tags is a helpful feature. To hide HTML tags, type C-c Tab; use the same command to display the tags again. Let's say that we've inserted some of our dickens file into the dickens.html file we were just working with.
您可以继续输入文本,专注于您正在编写的内容,而不是被标记分散注意力。 Emacs 通过将隐藏文本设置为只读来防止您在编写时删除标签。如果将光标移动到隐藏标签上,Emacs 会将其显示在迷你缓冲区中。
You can keep typing text, concentrating on what you're writing rather than being distracted by the markup. Emacs protects you from deleting tags when you're writing by making hidden text read-only. If you move the cursor onto a hidden tag, Emacs displays it in the minibuffer.
当然,编写 HTML 的全部目的是在 Web 浏览器中显示它。键入Cc Cv( 浏览 url-of-buffer)会打开默认的 Web 浏览器来查看您正在编写的网页。
Of course, the whole purpose of writing HTML is to display it in a web browser. Typing C-c C-v (for browse-url-of-buffer) opens the default web browser to view the web page you're writing.
如果您想在每次保存时在网络浏览器中查看文件,您可以打开一个名为html-autoview-mode的功能,通过按Cc Cs调用该 功能。当您保存文件时,Emacs 会自动在默认浏览器中打开它。
If you'd like to look at the file in a web browser each time you save, you can turn on a function called html-autoview-mode, invoked by pressing C-c C-s. When you save the file, Emacs automatically opens it in the default browser.
如果你想包括怎么办
网页中的特殊字符或其他字符集中的字符?简而言之,您可以显式输入字符的编码。例如,要输入带有变音符号的大写 U,您可以键入
Ü。许多字符也可以表示为命名实体,这当然比数字更容易记住。例如,带有变音符号的大写 U 的命名实体是Ü。
What if you want to include
special characters or characters from other character sets in your
web page? The short answer is that you can enter a
character's encoding explicitly. For example, to
enter a capital U with an umlaut, you can type
Ü. Many characters can also be
represented as named entities, which are certainly easier to remember
than numbers. For example, the named entity for a capital U with an
umlaut is Ü.
但 HTML 模式确实提供了比这更多的支持。我们首先考虑最简单的情况。假设您可以使用键盘创建一个角色;对于常见情况,采用 & 符号,该字符必须进行编码,因为它在 HTML 中具有特殊含义。输入
抄送 Cn 并输入。 Emacs 插入 & 符号实体,&。您可以通过这种方式为各种键盘字符插入实体。
But HTML mode does provide more support than this.
We'll take the simplest case first.
Let's say you can create a character with your
keyboard; for a common case, take the ampersand, a character that
must be encoded since it has a special meaning in HTML. Type
C-c C-n & Enter. Emacs inserts
the entity for an ampersand, &. You can
insert entities for a wide variety of keyboard characters this way.
但假设您正在插入键盘上没有的字符。例如,也许您在美国写一份来自欧洲的贡献者列表,其中许多人的名字都有重音符号。 ISO Latin-1 字符集将处理此问题。
But let's say that you are inserting characters that are not on your keyboard. For example, perhaps you are in the U.S. writing up a list of contributors from Europe and many of their names have accent marks. The ISO Latin-1 character set will handle this.
如果您的键盘已经发出 Latin-1 字符,并且 Latin-1 是键盘输入的默认编码系统,则插入此类字符相对简单。只需按Cc 8即可打开称为 SGML 名称实体模式的次要模式。 Emacs 说sgml name entity mode is now
on。[ 3 ]
Cc 8切换此状态。像平常一样输入 Latin-1 字符,Emacs 会插入与这些字符关联的命名实体。
If you have a keyboard that already emits Latin-1 characters and
Latin-1 is your default coding system for keyboard input, inserting
such characters is relatively straightforward. Simply press C-c 8 to turn on a minor mode called SGML name
entity mode. Emacs says sgml name entity mode is now
on.[3]
C-c
8 toggles this state. Type Latin-1 characters as you
normally would and Emacs inserts the named entities associated with
those characters.
然而,对于我们这些使用其他键盘编码的人来说,还有更多的事情要做。为了获得将实体插入 HTML 文件的绑定,我们讨论两个选项。第一个是 ISO 重音模式。顾名思义,此模式提供对重音文本的支持。无论您是输入变音符号、变音符号、扬抑符号、尖音符还是重音符,ISO 重音模式都可以胜任。另一种选择是使用Cx 8前缀插入各种实体,包括货币符号、数学符号和版权符号(以及 ISO 重音模式支持的所有重音字符)。
For those of us with other keyboard encodings, however, there's a bit more to do. To get bindings to insert entities into your HTML file, we discuss two options. The first is ISO accents mode. This mode provides support, as the name implies, for accented text. Whether you're typing umlauts, cedillas, circumflexes, acute, or grave marks, ISO accents mode is up to the task. The other option is to use the C-x 8 prefix to insert a wide range of entities, including currency signs, mathematical symbols, and copyright signs (as well as all the accented characters ISO accents mode supports).
使用 ISO 重音模式
要在文件中插入实体,请键入Cc 8以打开 SGML 名称实体模式,然后键入Mx iso-acents-mode Enter以打开该模式。在 ISO 重音模式下,某些字符(包括 /、~、'、"、` 和 ^)被解释为前缀以创建重音字符。SGML 名称实体模式捕获这些击键并自动插入适当的 HTML 实体。例如,键入'a
生成 á, 的 HTML 实体
á。有关特定键绑定,请参阅表 8-2。
To use ISO accents mode
to insert
entities in your file, type C-c 8 to
turn on SGML name entity mode, then M-x
iso-accents-mode Enter to turn on that mode. In ISO
accents mode, certain characters (including /, ~, ', ", `, and ^) are
interpreted as prefixes to create accented characters. SGML name
entity mode captures these keystrokes and automatically inserts the
appropriate HTML entity. For example, typing 'a
produces the HTML entity for á,
á. For specific key bindings, see Table 8-2.
在进行一些设置后,您还可以使用Cx 8插入各种实体。 [ 4 ]首先输入Cc 8进入 SGML 名称实体模式。接下来,通过键入Cx Enter k latin-1 Enter指定 Latin-1 作为字符集。然后,您可以通过键入前缀为Cx 8 的命令来输入大量实体。例如,要插入日元符号的实体,请输入Cx 8 Y。观察迷你缓冲区。当实体被插入时,文字字符将出现在迷你缓冲区中。 ISO 重音模式和Cx 8 前缀都允许您键入单个撤消命令 ( C-_ ) 将实体转换回文字字符。
You can also insert a wide range of entities using C-x 8 after you do some setup.[4] First enter SGML name entity mode by typing C-c 8. Next specify Latin-1 as your character set by typing C-x Enter k latin-1 Enter. You can then enter a large number of entities by typing commands prefixed with C-x 8. For example, to insert the entity for a yen symbol, type C-x 8 Y. Watch the minibuffer. The literal character will appear in the minibuffer as the entity is inserted. Both ISO accents mode and the C-x 8 prefixes allow you to type a single undo command (C-_) to translate the entity back into the literal character.
表 8-2提供了重音字符的列表以及有助于插入它们的绑定。表 8-3 列出了其他命名实体,包括标点符号和符号。
Table 8-2 provides a list of accented characters and the bindings that help insert them. Table 8-3 lists other named entities including punctuation marks and symbols.
表 8-2。用于插入重音字符实体的绑定[ 5 ]
Table 8-2. Bindings for inserting entities for accented characters[5]
表 8-3。用于插入标点和符号实体的绑定
Table 8-3. Bindings for inserting entities for punctuation and symbols
表 8-4列出了 HTML 模式命令。
Table 8-4 lists HTML mode commands.
表 8-4。 HTML 模式命令
Table 8-4. HTML mode commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
(没有任何) (none) |
html模式 html-mode |
进入 HTML 模式。 Enter HTML mode. |
|
抄送 Ct SGML → 插入标签 C-c C-t SGML → Insert Tag |
sgml标签 sgml-tag |
插入标签,提示输入属性。如果输入html作为标记名称,则会插入模板 html 文件。 Inserts a tag, prompting for attributes. If you enter html as the tag name, inserts a template html file. |
|
抄送选项卡 SGML → 切换标签可见性 C-c Tab SGML → Toggle Tag Visibility |
sgml-标签-不可见 sgml-tags-invisible |
隐藏或显示文件中的标签。 Hides or shows the tags in the file. |
|
抄送 Cv SGML → 查看缓冲区内容 C-c C-v SGML → View Buffer Contents |
浏览缓冲区的 url browse-url-of-buffer |
在默认浏览器中显示缓冲区。 Display buffer in default browser. |
|
铯铯 C-c C-s |
html-自动查看-模式 html-autoview- mode |
如果此模式打开(此命令切换它),则每次将文件保存在 Emacs 中时,都会在浏览器中显示文件。 If this mode is on (this command toggles it), display file in browser each time it is saved in Emacs. |
|
抄送8 C-c 8 |
sgml-名称-8位模式 sgml-name-8bit-mode |
如果打开,用于插入 Latin-1 字符的某些击键将被捕获并替换为适当的实体。详细信息请参见“HTML 模式下的字符编码”。 If turned on, certain keystrokes for inserting Latin-1 characters are captured and replaced with the appropriate entities. See "Character encoding in HTML mode" for details. |
|
抄送抄送 SGML → 转发标签 C-c C-f SGML → Forward Tag |
sgml-跳过标记-转发 sgml-skip-tag-forward |
前进到同一级别的下一个标签。 Move forward to the next tag of the same level. |
|
抄送 Cb SGML → 向后标记 C-c C-b SGML → Backward Tag |
sgml-向后跳过标记 sgml-skip-tag-backward |
向后移动到同一级别的上一个标签。 Move backward to previous tag of the same level. |
|
Cc Del 或 C-c Cd SGML → 删除标签 C-c Del or C-c C-d SGML → Delete Tag |
sgml 删除标签 sgml-delete-tag |
将光标置于标签上或标签之前,删除标签或标签对。 With cursor on or before a tag, deletes tag or tag pair. |
|
抄送1 C-c 1 |
html-标题-1 html-headline-1 |
插入一个 Insert an |
|
抄送2 C-c 2 |
html-标题-2 html-headline-2 |
插入一个 Insert an |
|
抄送3 C-c 3 |
html-标题-3 html-headline-3 |
插入一个 Insert an |
|
抄送4 C-c 4 |
html-标题-4 html-headline-4 |
插入一个 Insert an |
|
抄送5 C-c 5 |
html-标题-5 html-headline-5 |
插入一个 Insert an |
|
抄送6 C-c 6 |
html-标题-6 html-headline-6 |
插入 Insert an |
|
抄送输入 C-c Enter |
html 段落 html-paragraph |
插入 Insert |
|
抄送抄送 h HTML → Href 锚点 C-c C-c h HTML → Href Anchor |
html-href-锚点 html-href-anchor |
插入超链接。 Insert a hyperlink. |
|
抄送抄送 n HTML → 名称锚点 C-c C-c n HTML → Name Anchor |
html 名称锚点 html-name-anchor |
插入锚点,以便可以创建指向页面锚定部分的链接。 Insert an anchor so that a link can be created to the anchored part of the page. |
|
抄送 抄送 u HTML → 无序列表 C-c C-c u HTML → Unordered List |
html 无序列表 html-unordered-list |
创建项目符号列表。 Create a bulleted list. |
|
抄送 抄送 o HTML → 有序列表 C-c C-c o HTML → Ordered List |
html 有序列表 html-ordered-list |
创建一个编号列表。 Create a numbered list. |
|
抄送 抄送 l HTML → 列表项目 C-c C-c l HTML → List Item |
html 列表项 html-list-item |
将项目添加到列表中。 Add an item to a list. |
|
抄送抄送 i HTML → 图像 C-c C-c i HTML → Image |
html 图像 html-image |
插入 Insert |
|
抄送 Cj HTML → 换行符 C-c C-j HTML → Line Break |
html 行 html-line |
插入换行符 ( Insert a line break ( |
|
抄送抄送 - HTML → 水平规则 C-c C-c - HTML → Horizontal Rule |
html 水平规则 html-horizontal-rule |
插入水平线 ( Insert a horizontal rule ( |
|
抄送抄送 C-c C-c r |
html 单选按钮 html-radio-buttons |
插入一组单选按钮。 Emacs 提示输入组的名称,然后重复输入值、是否应检查它以及关联的文本。按Cg完成该组。 Insert a group of radio buttons. Emacs prompts for a name for the group, then repeatedly for value, whether it should be checked, and associated text. Press C-g to complete the group. |
|
抄送抄送 c HTML → 复选框 C-c C-c c HTML → Checkboxes |
html 复选框 html-checkboxes |
插入一组复选框。 Emacs 提示输入组的名称,然后重复输入值、是否应检查它以及关联的文本。按Cg完成该组。 Insert a group of checkboxes. Emacs prompts for a name for the group, then repeatedly for value, whether it should be checked, and associated text. Press C-g to complete the group. |
|
抄送? SGML → 描述标签 C-c ? SGML → Describe Tag |
sgml 标签帮助 sgml-tag-help |
提供光标位置标签的简短口头描述。 Provide brief verbal description of tag at cursor position. |
HTML 帮助器模式,编写者 Nelson Minar 现在由 Gian Uberto Lauri 维护,为编写 HTML 提供了极大的灵活性。您可以根据您的专业知识水平和偏好启用各种手持功能。
HTML helper mode, written by Nelson Minar and now maintained by Gian Uberto Lauri, offers great flexibility in writing HTML. You can enable various hand-holding features depending on your level of expertise and preferences.
为什么选择 HTML 帮助器模式而不是 Emacs 自己的 HTML 模式?尽管 HTML 模式可以轻松编写基本 HTML,但它对编程式交互式网页提供的支持很少。 HTML 帮助程序模式支持 ASP、JSP(以及 JDE,即 Java 开发环境,将在第 9 章中讨论)和 PHP,仅举几个更高级的功能。如果您在 Emacs 中编写 HTML,您很可能是此类页面的开发人员,而不是更面向文本的作者。因此,HTML 帮助程序模式在 Emacs 用户中继续流行。
Why would you choose HTML helper mode over Emacs's own HTML mode? Although HTML mode makes it easy to write basic HTML, it provides little support for programmatic, interactive web pages. HTML helper mode supports ASP, JSP (and JDE, the Java Development Environment, discussed in Chapter 9), and PHP, to name a few more advanced features. If you're writing HTML in Emacs, you're likely to be a developer of such pages rather than a more text-oriented author. For this reason, HTML helper mode continues to be popular among Emacs users.
默认情况下,Html 帮助程序模式不是 Emacs 的一部分。您可以从其主页下载: http://www.nongnu.org/baol-hth。将文件下载到目录(例如~/elisp )中,移动到该目录,然后键入:
Html helper mode is not part of Emacs by default. You can download it from its homepage at http://www.nongnu.org/baol-hth. Download the file into a directory such as ~/elisp, move to that directory, and then type:
%tar xvzf html-helper-mode.tar.gz% tar xvzf html-helper-mode.tar.gz系统会为您解压tar文件。 (当然,如果您在 Windows 上安装,则可以简单地使用 WinZip 解压并解压文件。)tar文件包含多个组件,包括:
The system unpacks the tar file for you. (Of course, if you are installing on Windows, you can simply use WinZip to decompress and unpack the file.) The tar file contains several components, including:
在启动 HTML 帮助程序之前
模式,您必须将其加载到 Emacs 中。 (有关该主题的完整讨论,请参阅第 11 章中的“构建您自己的 Lisp 库” ;我们在这里对其进行简要描述。)首先输入Mx load-file Enter。 Emacs 询问要加载哪个文件,您输入~/elisp/html-helper-mode.el
并按Enter,调整路径以反映安装
html-helper-mode.el的位置。您可以通过键入Mx html-helper-mode Enter进入该模式。
HTML helper出现在模式行上。
Before you can start HTML helper
mode, you
have to load it into Emacs. (For a complete discussion of this topic,
see "Building Your Own Lisp
Library" in Chapter 11; we
describe it briefly here.) Begin by typing M-x
load-file Enter. Emacs asks which file to load and you
enter ~/elisp/html-helper-mode.el
and press Enter, adjusting the path
to reflect the location where you installed
html-helper-mode.el. You enter the mode by
typing M-x html-helper-mode Enter.
HTML helper appears on the mode line.
让 HTML 帮助程序模式成为您启动的一部分会更容易。将以下行放入您的.emacs文件中:
Making HTML helper mode part of your startup is easier. Put the following lines in your .emacs file:
(setq 加载路径 (cons "~/elisp " 加载路径)) (自动加载'html-helper-mode“html-helper-mode”“Yay HTML”t)
(setq load-path (cons "~/elisp " load-path)) (autoload 'html-helper-mode "html-helper-mode" "Yay HTML" t)
在第一行中,在引号中插入html-helper-mode.el所在目录的完整路径,将~/elisp替换为适合您系统的正确值。第二行告诉 Emacs 在启动 Emacs 时自动加载 HTML 帮助程序模式。
In the first line, insert the complete path for the directory in which html-helper-mode.el is located in quotation marks, replacing ~/elisp to the correct value for your system. The second line tells Emacs to load HTML helper mode automatically when you start Emacs.
如果您想默认使用 HTML 帮助程序模式编辑 HTML 文件,请将此行添加到.emacs中:
If you want to use HTML helper mode for editing HTML files by default, add this line to .emacs as well:
(setq 自动模式列表 (cons '("\\.html?$" . html-helper-mode)
自动模式列表))(setq auto-mode-alist (cons '("\\.html?$" . html-helper-mode)
auto-mode-alist))如果您使用 HTML 帮助程序模式编辑其他类型的文件,您可能需要添加行以包含您编辑的所有类型的文件。添加更多行是最简单的方法。例如,要使 HTML 帮助程序模式成为 PHP 文件的默认模式,请将此行添加到.emacs:
If you edit other types of files with HTML helper mode, you may want to add lines to include all the types of files you edit. Adding more lines is the easiest way. For example, to make HTML helper mode the default for PHP files, add this line to .emacs:
(setq 自动模式列表 (cons '("\\.php$" . html-helper-mode)
自动模式列表))(setq auto-mode-alist (cons '("\\.php$" . html-helper-mode)
auto-mode-alist))人们喜欢 HTML 帮助程序模式的主要原因是它提供了对各种选项的轻松菜单访问。意识到拥有许多子菜单的拥挤菜单可能会让新用户不知所措,作者创建了一个名为“打开新手菜单”的选项。从 HTML 菜单中选择此选项将提供一个准系统菜单,如图8-1所示 。新手 HTML 编写者可以使用这些选项来创建基本的 HTML 文档,而不必担心表单、JSP、PHP 等的含义。
The main reason people like HTML helper mode is that it provides easy menu access to a wide variety of options. Realizing that having a crowded menu with many submenus could overwhelm new users, the authors created an option called Turn on Novice Menu. Selecting this option from the HTML menu provides a barebones menu, as shown in Figure 8-1. Novice HTML writers can use these options to create a basic HTML document without worrying about what forms, JSPs, PHP, and the like mean.
从 HTML 菜单中选择“打开专家菜单”将返回更大的菜单及其众多子菜单,如图8-2所示。
Selecting Turn on Expert Menu from the HTML menu returns the larger menu with its numerous submenus, as shown in Figure 8-2.
HTML 帮助器模式插入一个 每次创建新的 HTML 文件时都会为您提供模板。
HTML helper mode inserts a template for you every time you create a new HTML file.
|
类型:Cx Cf new.html Type: C-x C-f new.html |
|
|
|
HTML 帮助程序模式插入一个模板,其中包含有效 HTML 文档 (Windows) 所需的所有基本元素。 HTML helper mode inserts a template with all the basic elements needed for a valid HTML document (Windows). |
该模板包含所有基本 HTML 元素。整个文档都被
<html></html>标签包围。然后头部和身体分开。在<hr>
告诉浏览器插入水平线(称为水平线)的标签后面,<address>标签留下了一个位置供作者输入他或她的电子邮件地址。在垃圾邮件盛行的今天,您不太可能愿意这样做。 (您可以将该
<address>标签留空或删除。)
The template contains all the basic HTML elements. The entire
document is surrounded by
<html></html> tags. Then the head and
the body are separated. Following an <hr>
tag that tells the browser to insert a horizontal line, called a
horizontal rule, the <address> tag leaves a
place for the author to put in his or her email address. In these
days of spam, it's unlikely you'll
want to do that. (You can leave the
<address> tag blank or delete it.)
如果您确实想包含电子邮件地址,请在.emacs文件中输入如下行(当然,替换您自己的电子邮件地址):
If you do want to include an email address, enter a line like this in your .emacs file (substituting your own email address, of course):
(setq html-helper-地址-字符串 "<a href=\"mailto:cdickens@great-beyond.com "\>查尔斯·狄更斯</a>")
(setq html-helper-address-string "<a href=\"mailto:cdickens@great-beyond.com "\>Charles Dickens</a>")
|
类型:Cx Cf newfile.html Type: C-x C-f newfile.html |
|
|
|
Emacs 插入 HTML 模板,包括地址。 Emacs inserts the HTML template, including the address. |
通常,您通过输入标题和一级标题(这些通常是相同的)开始填写模板。然后您可以开始编写文本段落。在开始输入之前,请按M-Enter。 Emacs 将
<p></p>光标插入并定位在它们之间。您可以从结束段落标记中看到 HTML 帮助程序模式正在努力实现 XHTML 合规性。
Normally you begin filling out the template by entering title and a
level-one header (these are often the same). You can then begin
writing paragraphs of text. Before you start typing, press M-Enter. Emacs inserts
<p></p> and positions the cursor
between them. You can see from the ending paragraph tag that HTML
helper mode is working toward XHTML compliance.
编辑 HTML 文件时,您通常会花费大量时间来标记现有文本。如果您在任何标签命令前面加上Cu,Emacs 会在区域周围插入标签,而不是将它们放在光标位置。[ 7 ]为了进行演示,我们将启动一个新的 HTML 文件并插入来自 Dickens文件的文本。
When editing HTML files, you often spend a lot of time marking up existing text. If you preface any of the tag commands with C-u, Emacs inserts the tags around a region rather than putting them at the cursor position.[7] To demonstrate, we'll start a new HTML file and insert text from our dickens file.
|
类型:Cx Cf ataleoftwocities.html Type: C-x C-f ataleoftwocities.html |
|
|
|
Emacs 插入 HTML 模板。 Emacs inserts the HTML template. |
|
将光标移过该 Move the cursor past the |
|
|
|
Emacs 插入dickens文本文件,我们可以在其中添加 HTML 标签。 Emacs inserts the dickens text file, to which we can add HTML tags. |
如果你真的做得正确,你会输入类似“两个城市的故事,第 1 章”作为标题和一级标题。但现在,你只想看看如何标记现有的区域首先将 Dickens 段落标记为区域并输入Cu M-Enter。
If you were really doing this properly, you'd type something like "A Tale of Two Cities, Chapter 1 as the title and the first-level header. But for now, you just want to see how to mark up a region of existing text. Begin by marking the Dickens paragraph as a region and type C-u M-Enter.
HTML 帮助模式 支持完成。您键入标签的开头并按M-Tab(用于tempo-complete-tag)。[ 8 ] 如果有不止一种可能性,则会出现一个可能完成的窗口。假设您正在处理项目符号列表。
HTML helper mode supports completion. You type the beginning of a tag and press M-Tab (for tempo-complete-tag).[8] If there's more than one possibility, a window of possible completions appears. Let's say you are working on a bulleted list.
|
类型:<olM-Tab Type: <olM-Tab |
|
|
|
Emacs 插入列表开始和结束的标记以及一个列表项的标记。 Emacs inserts the tags to begin and end the list and the tag for one list item. |
但请注意,完成有时区分大小写。例如,输入<s M-Tab显示以下补全:
Note, however, that completion is sometimes case-sensitive. For example, typing <s M-Tab shows the following completions:
<选择<跨度类= <跨度样式 = <罢工> <强> <采样>
<select <span class= <span style = <strike> <strong> <samp>
请注意,<script>标签丢失了。但是,如果您尝试输入<S M-Tab,则会插入脚本标记及其属性,如下所示:
Notice that the <script> tag is missing. But
if you try typing <S M-Tab, the
script tag and its attributes are inserted, as in:
<脚本类型=“文本/javascript”> </脚本>
<SCRIPT TYPE="text/javascript"> </SCRIPT>
大写和小写之间的区别表明 HTML 帮助程序模式正在向 XHTML 合规性发展,但尚未完全实现。 XHTML 要求所有标签均为小写。从积极的一面来看,请注意该属性位于引号中,这是另一个 XHTML 要求。
The distinction between upper- and lowercase shows that HTML helper mode is moving toward XHTML compliance, but hasn't quite arrived. XHTML requires that all tags be lowercase. On the positive side, note that the attribute is in quotation marks, another XHTML requirement.
有些 HTML 标签需要您输入 某些属性。例如,当您输入超链接时,您必须指定链接的 URL 以及用户将选择的文本。如果您键入Cc Ca l(小写字母“L”)来输入链接,HTML 帮助程序模式会插入:
Some HTML tags require you to input certain attributes. For example, when you enter a hyperlink, you have to specify the URL of the link and the text that the user will select. If you type C-c C-a l (the lowercase letter "L") to enter a link, HTML helper mode inserts:
<a href=""></a>
<a href=""></a>
将光标放在第二个引号上,以便您可以输入 URL。如果您打开提示,HTML 帮助程序模式会提供额外的帮助。将此行添加到您的.emacs文件中:
with the cursor on the second quotation mark so you can type in the URL. HTML helper mode offers additional help if you turn on prompting. Add this line to your .emacs file:
(setq 节奏交互 t)
(setq tempo-interactive t)
请注意,HTML 帮助程序模式仅提示必需的属性;如果你想输入可选属性,你必须手动添加它们。
Note that HTML helper mode prompts only for required attributes; if you want to input optional attributes, you have to add them by hand.
您认为提示有用还是侵入性是个人喜好的问题。如果您是 HTML 新手,提示可能会帮助您记住为每个标签输入所有必要的信息。如果您发现不喜欢它,只需删除添加到.emacs文件中的行即可。
Whether you consider prompting useful or intrusive is a matter of personal taste. If you are a beginning HTML author, prompting may help you remember to enter all the necessary information for each tag. If you find you don't like it, simply delete the line you added to the .emacs file.
HTML 帮助器模式支持输入
仅最常见的字符实体。然而,它确实使插入这些实体变得容易。只需在相关字符前键入Cc即可。例如,键入Cc <可输入小于号 ( <) 的转义码。
HTML helper mode supports entry of
only the most common character
entities. However, it does make it easy to insert these entities.
Simply type C-c before the character
in question. For example, type C-c
< to enter the escape code for a less-than sign
(<).
还可以通过选择 HTML → 插入字符实体来使用字符实体。
Character entities are also available by selecting HTML→ Insert Character Entities.
表 8-5列出了用于在 HTML 帮助程序模式下插入字符实体的绑定。
Table 8-5 lists bindings for inserting character entities in HTML helper mode.
表 8-5。在 HTML 帮助程序模式下插入字符实体
Table 8-5. Inserting character entities in HTML helper mode
表 8-6列出了 HTML 帮助程序模式的键绑定。有用于高级 HTML 功能(例如表单)以及某些 HTML 3.0 功能的键绑定。某些标签通常会出现在不同的行上(例如,在列表的情况下);在此表中,它们显示在一行上。
Table 8-6 lists the key bindings for HTML helper mode. There are key bindings for advanced HTML features such as forms as well as for some of the HTML 3.0 features. Some tags would normally appear on different lines (for example, in the case of a list); in this table, they are shown on one line.
表 8-6。 HTML 帮助器模式命令
Table 8-6. HTML helper mode commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
铜 C-u |
普遍论证 universal-argument |
在任何其他标签命令之前使用时,在区域周围插入标签。 When used before any other tag command, insert tags around a region. |
|
M-标签 M-Tab |
节奏完整标签 tempo-complete-tag |
完成当前标签。 Complete the current tag. |
|
抄送 Cz v HTML → 在浏览器中加载此缓冲区 C-c C-z v HTML → Load This Buffer in Browser |
浏览文件 url browse-url-of-file |
在默认浏览器中显示此文件。 Display this file in the default browser. |
|
抄送 Cz u HTML → 浏览 URL 点 C-c C-z u HTML → Browse URL at Point |
浏览 url 默认浏览器 browse-url-default-browser |
在默认浏览器中加载该 URL。 Load the URL at point in default browser. |
|
抄送 Mh 1 HTML → 插入标头 → 标头 1 C-c M-h 1 HTML → Insert Headers → Header 1 |
节奏模板-html-header-1 tempo-template-html-header-1 |
插入 Insert |
|
抄送 Mh 2 HTML → 插入标头 → 标头 2 C-c M-h 2 HTML → Insert Headers → Header 2 |
节奏模板-html-header-2 tempo-template-html-header-2 |
插入 Insert |
|
抄送 Mh 3 HTML → 插入标头 → 标头 3 C-c M-h 3 HTML → Insert Headers → Header 3 |
节奏模板-html-header-3 tempo-template-html-header-3 |
插入 Insert |
|
抄送 Mh 4 HTML → 插入标头 → 标头 4 C-c M-h 4 HTML → Insert Headers → Header 4 |
节奏模板-html-header-4 tempo-template-html-header-4 |
插入 Insert |
|
抄送 Mh 5 HTML → 插入标头 → 标头 5 C-c M-h 5 HTML → Insert Headers → Header 5 |
节奏模板-html-header-5 tempo-template-html-header-5 |
插入 Insert |
|
抄送 Mh 6 HTML → 插入标头 → 标头 6 C-c M-h 6 HTML → Insert Headers → Header 6 |
节奏模板-html-header-6 tempo-template-html-header-6 |
插入 Insert |
|
M-输入 HTML → 插入文本元素 → 段落 M-Enter HTML → Insert Text Elements → Paragraph |
节奏模板 html 段落 tempo-template-html-paragraph |
插入 Insert |
|
抄送 HTML → 插入超链接 → 超链接 C-c C-a l HTML → Insert Hyperlinks → Hyperlink |
tempo-模板-html-超链接 tempo-template-html-hyperlink |
插入 Insert |
|
抄送 HTML → 插入超链接 → 目标 C-c C-a n HTML → Insert Hyperlinks → Target |
节奏模板 html 链接目标 tempo-template-html-link-target |
插入 Insert |
|
抄送输入 HTML → 插入文本元素 → 换行符 C-c Enter HTML → Insert Text Elements → Line Break |
节奏模板 html 换行符 tempo-template-html-line-break |
插入文字换行符, Insert a literal line break, |
|
抄送 = HTML → 插入文本元素 → 水平线 C-c = HTML → Insert Text Elements → Horizontal Line |
节奏模板 html 水平线 tempo-template-html-horizontal-line |
插入水平线, Insert a horizontal rule, |
|
抄送 Cz t HTML → 插入时间戳分隔符 C-c C-z t HTML → Insert Timestamp Delimiter |
html-helper-插入时间戳-定界符-点 html-helper-insert-timestamp-delimiter-at-point |
插入时间戳分隔符。 Insert timestamp delimiters. |
|
抄送 Ch t HTML → 插入结构元素 → 标题 C-c C-h t HTML → Insert Structural Elements → Title |
节奏模板 html 标题 tempo-template-html-title |
插入 Insert |
|
抄送 HTML → 插入内联图像 → 图像 C-c Tab a HTML → Insert Inlined Images → Image |
节奏模板 html 图像 tempo-template-html-image |
插入 Insert |
|
抄送 Cl u HTML → 插入列表元素 → 无序列表 C-c C-l u HTML → Insert List Elements → Unordered List |
tempo-模板-html-无序列表 tempo-template-html-unordered-list |
插入 Insert |
|
抄送 Cl o HTML → 插入列表元素 → 有序列表 C-c C-l o HTML → Insert List Elements → Ordered List |
tempo-模板-html-有序列表 tempo-template-html-ordered-list |
插入 Insert |
|
抄送 HTML → 插入列表元素 → 定义项 C-c C-l t HTML → Insert List Elements → Definition Item |
节奏模板 html 定义项目 tempo-template-html-definition-item |
插入 Insert |
|
抄送 HTML → 插入列表元素 → 列表项 C-c C-l l HTML → Insert List Elements → List Item |
节奏模板 html 项目 tempo-template-html-item |
插入 Insert |
|
抄送 HTML → 插入列表元素 → 定义列表 C-c C-l d HTML → Insert List Elements → Definition List |
节奏模板 html 定义列表 tempo-template-html-definition-list |
插入 Insert |
|
抄送 Cl m HTML → 插入列表元素 → 菜单列表 C-c C-l m HTML → Insert List Elements → Menu List |
节奏模板 html 菜单列表 tempo-template-html-menu-list |
插入
Insert
|
|
抄送 Cl r HTML → 插入列表元素 → 目录列表 C-c C-l r HTML → Insert List Elements → Directory List |
tempo-模板-html-目录列表 tempo-template-html-directorylist |
插入
Insert
|
|
抄送 Cl i HTML → 插入列表元素 → 列表项 C-c C-l i HTML → Insert List Elements → List Item |
html-helper-智能-插入-项目 html-helper-smart-insert-item |
插入 Insert |
|
抄送 Cf z HTML → 插入表单元素 → 其余表单 C-c C-f z HTML → Insert Form Elements → Rest Form |
节奏模板 html 重置表单 tempo-template-html-reset-form |
插入 Insert |
|
抄送抄送 b HTML → 插入表单元素 → 按钮 C-c C-f b HTML → Insert Form Elements → Button |
节奏模板 html 按钮 tempo-template-html-button |
插入 Insert |
|
抄送抄送 m HTML → 插入表单元素 → 提交表单 C-c C-f m HTML → Insert Form Elements → Submit Form |
tempo-模板-html-提交表单 tempo-template-html- submit-form |
插入 Insert |
|
抄送抄送 HTML → 插入表单元素 → 选择内容 C-c C-f s HTML → Insert Form Elements → Selections |
节奏模板 html 选择 tempo-template-html-selections |
插入 Insert |
|
抄送 Cf o HTML → 插入表单元素 → 选项 C-c C-f o HTML → Insert Form Elements → Option |
节奏模板 html 选项 tempo-template-html-option |
插入 Insert |
|
抄送 Cf v HTML → 插入表单元素 → 带值的选项 C-c C-f v HTML → Insert Form Elements → Option with Value |
节奏模板 html 选项带值 tempo-template-html-option-with-value |
插入 Insert |
|
抄送 Cf i HTML → 插入表单元素 → 图像字段 C-c C-f i HTML → Insert Form Elements → Image Field |
速度模板 html 输入图像字段 tempo-template-html-input-image-field |
插入 Insert |
|
抄送 HTML → 插入表单元素 → 单选按钮 C-c C-f r HTML → Insert Form Elements → Radiobutton |
节奏模板 html 输入单选按钮 tempo-template-html-input-radiobutton |
插入 Insert |
|
抄送 Cf c HTML → 插入表单元素 → 复选框 C-c C-f c HTML → Insert Form Elements → Checkbox |
节奏模板 html 复选框 tempo-template-html-checkbox |
插入 Insert |
|
抄送 Cf p HTML → 插入表单元素 → 文本区域 C-c C-f p HTML → Insert Form Elements → Text Area |
节奏模板 html 文本区域 tempo-template-html-text-area |
插入 Insert |
|
抄送 Cf f HTML → 插入表单元素 → 表单 C-c C-f f HTML → Insert Form Elements → Form |
节奏模板 html 形式 tempo-template-html-form |
插入 Insert |
|
抄送 Cf t `HTML → 插入表单元素 → 文本字段 C-c C-f t `HTML → Insert Form Elements → Text Field |
节奏模板 html 文本字段 tempo-template-html-text-field |
插入 Insert |
|
抄送 Cf h HTML → 插入表单元素 → 隐藏字段 C-c C-f h HTML → Insert Form Elements → Hidden Field |
节奏模板 html 隐藏字段 tempo-template-html-hidden-field |
插入 Insert |
|
抄送 Ml s HTML → 插入逻辑样式 → 强 C-c M-l s HTML → Insert Logical Styles → Strong |
节奏模板 html-strong tempo-template-html-strong |
插入 Insert |
|
抄送 Ml e HTML → 插入逻辑样式 → 强调 C-c M-l e HTML → Insert Logical Styles → Emphasized |
节奏模板 html 强调 tempo-template-html-emphasized |
插入 Insert |
|
抄送 Ml b HTML → 插入逻辑样式 → 块引用 C-c M-l b HTML → Insert Logical Styles → Blockquote |
tempo-模板-html-blockquote tempo-template-html-blockquote |
插入 Insert |
|
抄送 Ml p HTML → 插入逻辑样式 → 预格式化 C-c M-l p HTML → Insert Logical Styles → Preformatted |
节奏模板 html 预格式化 tempo-template-html-preformatted |
插入 Insert |
|
抄送 Cp s HTML → 插入物理样式 → 删除线 C-c C-p s HTML → Insert Physical Styles → Strikethru |
节奏模板 html-strikethru tempo-template-html-strikethru |
插入 Insert |
|
抄送 Cp f HTML → 插入物理样式 → 固定 C-c C-p f HTML → Insert Physical Styles → Fixed |
节奏模板 html 固定 tempo-template-html-fixed |
插入 Insert |
|
抄送 Cp u HTML → 插入物理样式 → 下划线 C-c C-p u HTML → Insert Physical Styles → Underline |
节奏模板 html 下划线 tempo-template-html-underline |
插入 Insert |
|
抄送 Cp i HTML → 插入物理样式 → 斜体 C-c C-p i HTML → Insert Physical Styles → Italic |
节奏模板 html 斜体 tempo-template-html-italic |
插入 Insert |
|
抄送 Cp b HTML → 插入物理样式 → 粗体 C-c C-p b HTML → Insert Physical Styles → Bold |
节奏模板 html 粗体 tempo-template-html-bold |
插入 Insert |
|
抄送 Cp c HTML → 插入物理样式 → 居中 C-c C-p c HTML → Insert Physical Styles → Center |
节奏模板 html 中心 tempo-template-html-center |
插入 Insert |
|
抄送 Cp l HTML → 插入物理样式 → 跨越类 C-c C-p l HTML → Insert Physical Styles → Spanning Class |
节奏模板 html 跨度类 tempo-template-html-spanning-class |
插入 Insert |
|
抄送 Cp 5 HTML → 插入物理样式 → 跨越样式 C-c C-p 5 HTML → Insert Physical Styles → Spanning Style |
节奏模板 html 跨度样式 tempo-template-html-spanning-style |
插入 Insert |
|
抄送 HTML → 插入逻辑样式 → 地址 C-c C-s a HTML → Insert Logical Styles → Address |
节奏模板 html 地址 tempo-template-html-address |
插入 Insert |
|
抄送 Ml d HTML → 插入逻辑样式 → 定义 C-c M-l d HTML → Insert Logical Styles → Definition |
节奏模板 html 定义 tempo-template-html-definition |
插入 Insert |
|
抄送 Ml v HTML → 插入逻辑样式 → 变量 C-c M-l v HTML → Insert Logical Styles → Variable |
速度模板 html 变量 tempo-template-html-variable |
插入 Insert |
|
抄送 Ml k HTML → 插入逻辑样式 → 键盘输入 C-c M-l k HTML → Insert Logical Styles → Keyboard Input |
节奏模板 html 键盘 tempo-template-html-keyboard |
插入 Insert |
|
抄送 Ml r HTML → 插入逻辑样式 → 引文 C-c M-l r HTML → Insert Logical Styles → Citation |
节奏模板 html 引用 tempo-template-html-citation |
插入 Insert |
|
抄送 Ml x HTML → 插入逻辑样式 → 示例 C-c M-l x HTML → Insert Logical Styles → Sample |
节奏模板 html 样本 tempo-template-html-sample |
插入 Insert |
|
抄送 Ml c HTML → 插入逻辑样式 → 代码 C-c M-l c HTML → Insert Logical Styles → Code |
节奏模板 html 代码 tempo-template-html-code |
插入 Insert |
|
抄送 Ch b HTML → 插入结构元素 → 基础 C-c C-h b HTML → Insert Structural Elements → Base |
节奏模板 html 基础 tempo-template-html-base |
插入 Insert |
|
抄送 Ch l HTML → 插入结构元素 → 链接 C-c C-h l HTML → Insert Structural Elements → Link |
节奏模板 html 链接 tempo-template-html-link |
插入 Insert |
|
抄送 Ch m HTML → 插入结构元素 → 元名称 C-c C-h m HTML → Insert Structural Elements → Meta Name |
节奏模板 html 元名称 tempo-template-html-meta-name |
插入 Insert |
|
抄送 CH n HTML → 插入结构元素 → Nextid C-c C-h n HTML → Insert Structural Elements → Nextid |
节奏模板 html-nextid tempo-template-html-nextid |
插入 Insert |
|
抄送 Chi HTML → 插入结构元素 → Isindex C-c C-h i HTML → Insert Structural Elements → Isindex |
节奏模板 html-isindex tempo-template-html-isindex |
插入 Insert |
|
抄送 Ch B HTML → 插入结构元素 → 正文 C-c C-h B HTML → Insert Structural Elements → Body |
节奏模板 html 正文 tempo-template-html-body |
插入 Insert |
|
抄送 Ch H HTML → 插入结构元素 → 头部 C-c C-h H HTML → Insert Structural Elements → Head |
节奏模板 html 头 tempo-template-html-head |
插入 Insert |
|
抄送 Ct t HTML → 插入表格 → 表格 C-c C-t t HTML → Insert Tables → Table |
节奏模板 html 表 tempo-template-html-table |
插入 Insert |
|
抄送 Ct p HTML → 插入表格 → html 表格标题 C-c C-t p HTML → Insert Tables → html table caption |
tempo-模板-html-html-table-标题 tempo-template-html-html-table-caption |
插入 Insert |
|
抄送 Ct d HTML → 插入表格 → 表格数据 C-c C-t d HTML → Insert Tables → Table Data |
节奏模板 html 表数据 tempo-template-html-table-data |
插入 Insert |
|
抄送 Ct h HTML → 插入表格 → 表头 C-c C-t h HTML → Insert Tables → Table Header |
节奏模板 html-table-header tempo-template-html-table-header |
插入 Insert |
|
抄送中心 C-c C-t r HTML → 插入表格 → 表格行 HTML → Insert Tables → Table Row |
节奏模板 html 表格行 tempo-template-html-table-row |
插入 Insert |
[ 1 ] SGML 代表标准化通用标记语言。 XML 和 HTML 都是 SGML 的后代。
[1] SGML stands for standardized general markup language. Both XML and HTML are descendants of SGML.
[ 2 ]在撰写本文时,还没有办法显式地进入 XHTML 模式。如果您的文件看起来像 XHTML 文件,Emacs 会自动将您置于该模式。
[2] At this writing, there is no way to enter XHTML mode explicitly. If your file looks like an XHTML file, Emacs puts you in that mode automatically.
[ 3 ]不要注意这被称为 SGML 与 HTML 名称实体模式。由于 HTML 模式源自 SGML 模式,因此许多使用 HTML 的命令的名称中都包含 sgml。另请注意,该命令称为sgml-name-8bit-mode,与迷你缓冲区消息存在明显差异。
[3] Pay no attention to the fact that this is called SGML versus HTML name entity mode. Since HTML mode is derived from SGML mode, many commands that work with HTML have sgml in their names. Also, note that the command is called sgml-name-8bit-mode, a clear discrepancy with the minibuffer message.
[ 4 ]由于某种原因,也许是 SGML 名称实体模式的编程方式,您只能使用键绑定插入这些实体。该模式无法捕获等效命令并将其转换为实体。因此,我们重点关注键绑定。
[4] For some reason, perhaps the way SGML name entity mode is programmed, you can insert these entities only using key bindings. The mode fails to trap the equivalent commands and translate them into entities. For this reason, we focus on key bindings.
[ 6 ]我们在 2004 年 8 月下载的版本将此文件标记为 alpha 代码,因此如果您发现错误,请不要感到惊讶。访问该文件以查看其状态是否已更改。
[6] The version we downloaded in August 2004 marked this file as alpha code, so don't be surprised if you find bugs. Visit the file to see if its status has changed.
编写 XML 涉及输入结构化数据 符合文档类型定义或架构的信息。即使在 Emacs 中,您获得的 XML 支持也各不相同。在频谱的低端,有普通的基本模式。它仅提供一个供您键入的屏幕。 SGML 模式等专用模式提供对输入标签的支持,正如我们之前在讨论 HTML 模式(SGML 模式的衍生形式)中所看到的那样。但这些方法都不能帮助您解析或验证 XML(SGML 模式有一个用于验证的命令,但正确设置很棘手)。更高级的 Lisp 包虽然目前未包含在 Emacs 中,但可以提供这些功能。这些附加包提供针对 DTD 或模式的验证、解析功能以及通常的一系列标准 DTD 和模式定义。在 Emacs 中,这些工具主要与两种主要模式之一结合使用。 psgml 模式根据 DTD 验证 XML(和 SGML)。较新的 nxml 模式根据 RELAX NG 模式进行验证。我们在本节中介绍这两个选项。不过,在详细介绍这些模式之前,让我们先简要了解一下 Emacs 内置的 SGML 模式。
Writing XML involves entering structured information that complies with a document type definition or schema. Even within Emacs, the XML support you receive varies. At the low end of the spectrum, there is plain vanilla Fundamental mode. It provides simply a screen where you type. Specialized modes like SGML mode provide support for entering tags, as we saw earlier in our discussion of HTML mode, a derivative of SGML mode. But neither of these approaches help you parse or validate XML (SGML mode has a command for validating, but it is tricky to set up correctly). More advanced Lisp packages, though currently not included in Emacs, are available to provide these functions. These add-on packages provide validation against DTDs or schemas, parsing capabilities, and, typically, an array of standard DTDs and schema definitions. In Emacs, these tools primarily work in conjunction with one of two major modes. psgml mode validates XML (and SGML) against DTDs. The newer nxml mode validates against RELAX NG schemas. We cover both of these options in this section. Before we go into detail on those modes, however, let's look briefly what Emacs has built-in with SGML mode.
Emacs 自己的 SGML 模式提供 支持输入标签。我们之前在 HTML 模式下介绍了大部分内容,因此我们在这里仅提供一个简短的示例。插入、隐藏和显示标签是 SGML 模式提供的特别有用的功能。
Emacs's own SGML mode provides support for entering tags. We covered much of this earlier under HTML mode, so we provide just one brief example here. Inserting, hiding, and showing tags are especially helpful features provided by SGML mode.
让我们看一下 《Java in a Nutshell》作者 David Flanagan 撰写的关于枚举类型的一章。本章使用 DocBook DTD。
Let's look at a chapter on enumerated types by Java in a Nutshell author David Flanagan. This chapter uses the DocBook DTD.
|
初始状态: Initial state: |
|
|
|
编辑使用 DocBook DTD (Mac OS X) 的文档。 Editing a document that uses the DocBook DTD (Mac OS X). |
请注意,Emacs 在模式行上显示 XML。在这种情况下,XML 模式是 SGML 模式的子集。实际上,尽管有这个名称,但此模式下的所有命令都以 sgml 开头,而不是 xml。相关命令的菜单也称为SGML。 Emacs 并不假装拥有广泛的 XML 支持。
Note that Emacs displays XML on the mode line. XML mode in this context is a subset of SGML mode. Actually, despite this name, all the commands in this mode start with sgml, not xml. The menu of relevant commands is called SGML as well. Emacs doesn't pretend to have extensive XML support.
我们想在第一段之前插入一段。
We want to insert a paragraph before the first paragraph.
|
在标题后面添加一个空行并键入:抄送 Ct Add a blank line following the title and type: C-c C-t |
|
|
|
Emacs 插入一个左尖括号并提示输入标签名称 (Mac OS X)。 Emacs inserts an open angle bracket and prompts for the tag name (Mac OS X). |
|
类型:para Enter Type: para Enter |
|
|
|
Emacs 插入开始和结束段落标签 (Mac OS X)。 Emacs inserts opening and closing paragraph tags (Mac OS X). |
请注意,Emacs 不遵循我们的缩进样式。我们可以通过移动到行的开头并按 Tab来更正它。有关 SGML 模式命令的详细信息,请参阅本章前面的表 8-4 。
Note that Emacs is not following our indentation style. We can correct it by moving to the beginning of the line and pressing Tab. See Table 8-4 earlier in this chapter for details on SGML mode commands.
文本编码倡议 (TEI) 想要为 Emacs 提供一个 XML 创作环境,因此它创建了(名称有些误导性的)TEI Emacs。[ 9 ]尽管有其名称,TEI Emacs 并不包含 Emacs 本身。相反,它创建了一个使用 nxml 模式或 psgml 模式编写 XML 的创作环境。它结合了 XSLT 工具以及大多数标准 DTD,例如三种形式的 XHTML DTD(严格、框架集和过渡)、DocBook DTD 等。当然,TEI 自己的 DTD 和模式也包括在内。
The Text Encoding Initiative (TEI) wanted an XML authoring environment for Emacs, so it created (the somewhat misleadingly named) TEI Emacs.[9] Despite its name, TEI Emacs does not include Emacs itself. Rather, it creates an authoring environment for writing XML using nxml mode or psgml mode. It incorporates XSLT tools, along with most of the standard DTDs, such as the three forms of XHTML DTDs (strict, frameset, and transitional), DocBook DTDs, and more. Naturally, the TEI's own DTDs and schemas are also included.
尽管在撰写本文时该工具仅限于 Linux 和 Windows,但该工具的积极开发及其精心包装促使我们描述了该工具。[ 10 ]在安装此工具之前,您应该已经安装了 Emacs 21.3。安装 TEI Emacs 很简单。 Windows 版本有一个安装程序,Linux 用户按照http://www.tei-c.org/Software/tei-emacs/(下载 TEI Emacs 的网站)上的简单说明进行操作。
The active development of this tool and its careful packaging led us to describe this tool despite the fact that it is limited to Linux and Windows at this writing.[10] You should have Emacs 21.3 already installed before you install this tool. Installing TEI Emacs is trivial. The Windows version has an installer, and Linux users follow simple instructions at http://www.tei-c.org/Software/tei-emacs/, the web site for downloading TEI Emacs.
James Clark,XML 先驱, 编写了 nxml 模式来为他的模式标准 RELAX NG 提供 Emacs 支持。有关该标准的详细信息,请访问http://www.relaxng.org/或获取 Eric van der Vlist (O'Reilly) 编写的RELAX NG副本。 nxml 模式的重要一点是,它会在您键入时验证文本,而不是将验证和调试分开进行。
James Clark, an XML pioneer, wrote nxml mode to provide Emacs support for his schema standard RELAX NG. For details on the standard, visit http://www.relaxng.org/ or pick up a copy of RELAX NG by Eric van der Vlist (O'Reilly). The important thing about nxml mode is that it validates text as you type instead of making validation and debugging separate steps.
如果您没有安装 TEI Emacs,您可以从http://thaiopensource.com/download/下载 nxml 模式及其架构。如果您决定成为活跃的 nxml 模式用户,您可能需要加入相关的 Yahoo Group 讨论列表(请参阅http://groups.yahoo.com/group/emacs-nxml-mode/)。
If you did not install TEI Emacs, you can download nxml mode and its schemas from http://thaiopensource.com/download/. If you decide to become an active nxml mode user, you may want to join a related Yahoo Group discussion list (see http://groups.yahoo.com/group/emacs-nxml-mode/).
在本节中,我们将运行的 HTML 示例更改为 XHTML,首先使用 RELAX NG 模式和 nxml 模式。打开 dickens.html,然后进入 nxml 模式。
In this section, we change our running HTML example to XHTML, first using a RELAX NG schema and nxml mode. Open dickens.html, then enter nxml mode.
|
类型:Cx Cf dickens.html 输入 Mx nxml-mode 输入 Type: C-x C-f dickens.html Enter M-x nxml-mode Enter |
|
|
|
在 nxml 模式下编辑dickens.html 。 Editing dickens.html in nxml mode. |
nxml 模式告诉您它在迷你缓冲区中使用什么模式。它足够聪明,知道它的 XHTML 架构最适合此目的。
nxml mode tells you what schema it is using in the minibuffer. It's smart enough to know that its XHTML schema is best for this purpose.
模式行告诉我们该文件当前无效。 Emacs 用红色下划线突出显示错误。让我们一次处理一个错误。
The mode line tells us that this file is currently invalid. Emacs highlights errors with red underscores. Let's deal with these errors one at a time.
|
将光标移动到 html 标记末尾的红色下划线处。 Move the cursor to the red underscore at the end of the html tag. |
|
|
|
迷你缓冲区描述了缺少的内容。 The minibuffer describes what's missing. |
使用模式编辑 XHTML 需要在
<html>标签中定义命名空间。 nxml模式知道我们需要什么。现在是使用 nxml 的补全功能让它为我们提供详细信息的好时机。C-Enter完成当前标签。
Editing XHTML with a schema requires a namespace definition in the
<html> tag. nxml mode knows what we need.
This is a good time to use nxml's completion feature
to let it supply the details for us. C-Enter completes the current tag.
|
类型:空格 xmlns= " C-Enter Type: Space xmlns=" C-Enter |
|
|
|
Emacs 插入命名空间声明的其余部分。 Emacs inserts the rest of the namespace declaration. |
模式行告诉我们该文件仍然无效。转到带下划线的地址标签给了我们一个相当神秘的原因;它说,
Element not allowed in this context。让我们转到结束正文标记,看看该错误是否提供了对问题的更多见解。
The mode line tells us that this file is still invalid. Moving to the
underlined address tag gives us a fairly cryptic reason; it says,
Element not allowed in this context.
Let's move down to the closing body tag to see if
that error provides any more insight into the problem.
这条消息提供了一条线索。尽管 HTML 作者不习惯在段落中添加结束标记,但 XHTML 需要它们。让我们在段落后面插入一个结束标记。
This message provides a clue. Although HTML authors are not accustomed to adding closing tags to paragraphs, XHTML requires them. Let's insert a closing tag after our paragraph.
|
移至狄更斯段落后面的行并输入:</ Move to the line following the Dickens paragraph and type: </ |
|
|
|
Emacs 插入结束标记。 Emacs inserts a closing tag. |
请注意,只需键入</就足以为当前元素插入结束标记。我们不需要输入C-Enter来调用完成。这是因为在 nxml 模式下,斜杠绑定到 nxml-electric-slash。它会自动完成最近的开放元素,这是我们的另一个快捷方式。
Note that just typing </ was adequate to insert a closing tag for the current element. We don't need to type C-Enter to invoke completion. That's because in nxml mode, slash is bound to nxml-electric-slash. It automatically completes the nearest open element, another shortcut for us.
类似的命令是Cc Cf(用于 nxml-finish-element)。使用Cc Cf,您无需输入任何内容;它会为您插入相关的结束标签。
A similar command is C-c C-f (for nxml-finish-element). With C-c C-f, you don't have to type anything; it inserts the relevant closing tag for you.
现在看看模式线。它说有效。使用 nxml 模式,获取 HTML 文件并将其更改为有效的 XHTML 并不是太困难。
Look at the mode line now. It says valid. Using nxml mode, it's not too tough to take an HTML file and change it to valid XHTML.
在键入文本时验证文本是 nxml 模式的一个关键功能。它正在根据模式进行验证。要指定不同的架构,请键入Cc Cs(对于 rng-set-schema-and-validate)。迷你缓冲区会提示输入架构所在的文件。可以在http://www.relaxng.org/#schemas在线找到许多模式。您还可以使用该页面上列出的工具将 DTD 转换为架构。
Validating text as you type it is a key feature of nxml mode. It's validating against a schema. To specify a different schema, type C-c C-s (for rng-set-schema-and-validate). The minibuffer prompts for the file where the schema resides. A number of schemas can be found online at http://www.relaxng.org/#schemas. You can also convert DTDs to schemas using tools listed on that page.
您的菜单会有所不同,具体取决于您是直接安装 nxml 模式还是使用 TEI 的版本。 TEI 使用 UniChar 菜单提供对编码字符的支持。它还提供广泛的 XSLT 支持。 TEI 的 NXML 菜单包括一些 TEI 框架以及 nxml 模式选项。从thaiopensource.org安装的 Nxml 模式包括一个 XML 菜单,其中包含用于设置架构和自定义模式的选项。表 8-7列出了 nxml 模式下可用的一些命令。
Your menus vary depending on whether you install nxml mode directly or whether you use TEI's version. TEI provides support for encoded characters using the UniChar menu. It also provides extensive XSLT support. TEI's NXML menu includes some TEI skeletons as well as nxml mode options. Nxml mode installed from thaiopensource.org includes an XML menu with options for setting the schema and customizing the mode. Table 8-7 lists some of the commands available in nxml mode.
表 8-7。 Nxml 模式命令
Table 8-7. Nxml mode commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
中心 C-Enter |
nxml 完整 nxml-complete |
完成当前标签。 Complete the current tag. |
|
/ / |
nxml-电斜杠 nxml-electric-slash |
为最后一个打开的元素添加结束标签。 Add a closing tag for the last open element. |
|
抄送中国 C-c C-n |
rng-下一个错误 rng-next-error |
移至下一个错误。 Move to the next error. |
|
氯化铜 C-c C-l |
rng 保存架构位置 rng-save-schema-location |
在您的主目录中创建(或更新)名为schemas.xml的文件。该文件将模式与文件关联起来。 Creates (or updates) a file called schemas.xml in your home directory. This file associates schemas with files. |
|
铯铯 C-c C-s |
rng-设置架构并验证 rng-set-schema-and-validate |
设置架构并对其进行验证。 Set the schema and validate against it. |
|
抄送钙 C-c C-a |
rng 自动设置架构 rng-auto-set-schema |
根据文件内容自动设置架构。 Set the schema automatically according to the contents of the file. |
|
抄送CW C-c C-w |
rng 内容模式 rng-what-schema |
在迷你缓冲区中显示与该文件关联的当前模式。 Show in the minibuffer the current schema associated with this file. |
|
抄送CV C-c C-v |
rng-验证模式 rng-validate-mode |
切换模式行指示文件有效还是无效。 Toggles whether the mode line indicates that the file is valid or invalid. |
|
铜铜 C-c C-u |
nxml-插入命名字符 nxml-insert-named-char |
插入一个命名字符;按Tab 键 查看列表。 Insert a named character; press Tab to see a list. |
|
(没有任何) (none) |
nxml-插入-xml-声明 nxml-insert-xml-declaration |
在文件开头插入 XML 声明。 Insert an XML declaration at the beginning of the file. |
|
抄送选项卡 C-c Tab |
nxml-平衡-关闭-开始-标签-内联 nxml-balanced-close-start-tag-inline |
插入您正在键入的开始标记的结束标记,并将结束标记放在当前行上。 Insert the ending tag for the starting tag you are typing, putting the ending tag on the current line. |
|
抄送 抄送 C-c C-b |
nxml-平衡-关闭-开始-标记-块 nxml-balanced-close-start-tag-block |
插入您正在键入的起始标记的结束标记,并将结束标记放在单独的行上。 Insert the ending tag for the starting tag you are typing, putting the ending tag on a separate line. |
|
抄送 抄送 C-c C-f |
nxml 完成元素 nxml-finish-element |
完成当前元素。 Finish the current element. |
|
姆赫 M-h |
nxml 标记段落 nxml-mark-paragraph |
标记当前段落。 Mark the current paragraph. |
|
M-} M-} |
nxml 前向段落 nxml-forward-paragraph |
向前移动一段。 Move forward one paragraph. |
|
M-{ M-{ |
nxml 向后段落 nxml-backward-paragraph |
后移一段。 Move back one paragraph. |
|
CMp C-M-p |
nxml-向后元素 nxml-backward-element |
向后移动一个元素。 Move back one element. |
|
锰 C-M-n |
nxml-前向元素 nxml-forward-element |
向前移动一个元素。 Move forward one element. |
|
CMd C-M-d |
nxml-down-元素 nxml-down-element |
向下移动一个元素(如果嵌套)。 Move down one element (if nested). |
|
CMu C-M-u |
nxml 向后向上元素 nxml-backward-up-element |
上移一个元素(如果嵌套)。 Move up one element (if nested). |
Lennart Stafflin 的 psgml 模式已 周围了一段时间。它比 Emacs 自己的 SGML 模式更强大,但是,像任何附加组件一样,您必须安装它才能使用它。如前所述安装 TEI Emacs 或从http://www.lysator.liu.se/projects/about_psgml.html下载 psgml 模式 并按照那里的安装说明进行操作。 TEI Emacs 包含一个有效的 psgml 模式,因此如果您已经安装了 TEI Emacs,那么您的设置工作就已完成。
Lennart Stafflin's psgml mode has been around for a while. It is more robust than Emacs's own SGML mode, but, like any add-on, you have to install it in order to use it. Either install TEI Emacs as described earlier or download psgml mode from http://www.lysator.liu.se/projects/about_psgml.html and follow the installation instructions there. TEI Emacs includes a functioning psgml mode, so if you've installed TEI Emacs, your setup work is done.
psgml 模式由两部分组成:用于编写 SGML 的 sgml-mode 和用于编写 XML(在我们的例子中为 XHTML)的 xml-mode。
psgml mode consists of two parts: sgml-mode for writing SGML and xml-mode for writing XML (and in our case XHTML).
|
要启动 psgml 模式来编辑 XHTML 文件,请输入Mx xml-mode。 To start psgml mode to edit our XHTML file, type M-x xml-mode. |
|
|
|
XML 出现在模式行上并 XML appears on the mode line and an |
该*SGML LOG*窗口显示有关此会话的消息。 (如果它没有立即出现,请单击文件中的第一个字符。)日志缓冲区抱怨它找不到名为 html 的外部实体。该文件已更改为可与 XHTML RELAX NG 模式一起使用。 psgml 模式期望它符合 XHTML DTD。为了开始进行从基于模式的文件到基于 DTD 的文件的转换所需的(最少)工作,我们要求 psgml 规范化缓冲区。
The *SGML LOG* window displays messages about this
session. (If it doesn't appear immediately, click on
the first character in the file.) The log buffer complains that it
could not find an external entity called html. This file has been
changed to work with the XHTML RELAX NG schema. psgml mode expects it
to conform to an XHTML DTD. To get started with the (minimal) work
needed to undertake the transformation from a schema-based file to a
DTD-based file, we ask psgml to normalize the buffer.
|
类型:Mx sgml-normalize或从“修改”菜单中选择“标准化” Type: M-x sgml-normalize or select Normalize from the Modify menu |
|
|
|
psgml 模式消除了标签中的命名空间声明
psgml mode eliminates the namespace declaration in the
|
然而,还需要做更多的工作。 XHTML 文件中的第一个语句包括 XML 语句和 DOCTYPE 条目,该条目标识应验证此文档的 DTD。 TEI Emacs 的优点之一是它包含各种 DTD。 (标准 psgml 模式的用户没有此功能;抱歉。[ 11 ])
More needs to be done, however. The first statements in an XHTML file include an XML statement and a DOCTYPE entry that identifies the DTD this document should be validated against. One of the nice things about TEI Emacs is that it includes a variety of DTDs. (Users of standard psgml mode don't have this feature; sorry.[11])
|
在文件的开头,选择 DTD →插入 DTD → XHTML Transitional。 At the beginning of the file, select DTD→ Insert DTD→ XHTML Transitional. |
|
|
|
Emacs 为我们插入了两个必需的元素。 Emacs inserts the two required elements for us. |
这就是使该文件成为格式良好的 XHTML 文件所需的全部操作。 psgml 模式允许针对 DTD 进行验证。让我们使用Cc Cv来验证它,以确保它没问题。
That's all it takes to make this file a well-formed XHTML file. psgml mode allows for validation against the DTD. Let's validate it using C-c C-v to make sure it's okay.
|
类型:抄送抄送 Type: C-c C-v |
|
|
|
psgml 模式在迷你缓冲区中插入默认的验证命令;按Enter运行它。 psgml mode inserts the default validate command in the minibuffer; press Enter to run it. |
|
出现提示时按Enter并键入y保存缓冲区 Press Enter and type y to save the buffer when prompted |
|
|
|
缓冲区 The |
当然,典型的文档比这个复杂得多。 “视图”菜单上的选项提供元素的选择性隐藏和显示,包括隐藏所有标签的选项,使您可以专注于文件的内容。
Of course, typical documents are far more complex than this one. Options on the View menu provide selective hiding and showing of elements, including an option to hide all tags, allowing you to focus on the content of the file instead.
psgml 模式还提供了许多选项。如果您正在运行 TEI Emacs,您将在 XML/SGML 菜单上找到“文件选项”和“用户选项”子菜单。如果您已独立安装 psgml 模式,您将在 SGML 菜单上找到它们。表 8-8总结了一些 psgml 命令。
psgml mode also offers numerous options. If you are running TEI Emacs, you'll find the File Options and User Options submenus on the XML/SGML menu. If you've installed psgml mode standalone, you'll find them on the SGML menu. Table 8-8 summarizes some of the psgml commands.
表 8-8。 psgml 模式下的绑定
Table 8-8. Bindings in psgml mode
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CM空间 C-M-Space |
sgml 标记元素 sgml-mark-element |
标记当前元素。 Mark the current element. |
|
M-标签 M-Tab |
sgml 完整 sgml-complete |
完成当前标签。 Complete the current tag. |
|
CMt C-M-t |
sgml 转置元素 sgml-transpose-element |
转置两个元素。 Transpose two elements. |
|
CMh C-M-h |
sgml 标记当前元素 sgml-mark-current-element |
标记当前元素。 Mark the current element. |
|
CMk 修改 → 删除元素 C-M-k Modify → Kill Element |
sgml 杀死元素 sgml-kill-element |
删除当前元素(以及所有子元素)。 Delete the current element (and any child elements). |
|
CMu 移动 → 向后向上元素 C-M-u Move → Backward Up Element |
sgml 向后向上元素 sgml-backward-up-element |
向上移动到该元素的父元素。 Move up to the parent element for this element. |
|
CMd 移动 → 向下元素 C-M-d Move → Down Element |
sgml-向下元素 sgml-down-element |
向下移动到下一个子元素。 Move down to the next child element. |
|
CMb 移动 → 向后元素 C-M-b Move → Backward Element |
sgml 向后元素 sgml-backward-element |
移至上一个元素。 Move to the previous element. |
|
CMf 移动 → 向前元素 C-M-f Move → Forward Element |
sgml-前向元素 sgml-forward-element |
移至下一个元素。 Move to the next element. |
|
CMe 移动 → 元素结束 C-M-e Move → End of Element |
sgml 元素结尾 sgml-end-of-element |
移动到当前元素的末尾。 Move to the end of the current element. |
|
CMa 移动 → 元素开始 C-M-a Move → Beginning of Element |
sgml 元素开头 sgml-beginning-of-element |
移至当前元素的开头。 Move to the beginning of the current element. |
|
抄送 Cw SGML → 什么元素 C-c C-w SGML → What Element |
sgml-什么-元素 sgml-what-element |
与 sgml-position 类似,但根据标签与内容描述层次结构(例如,html 中 head 标题中的开始标签)。 Similar to sgml-position but describes hierarchy in terms of tags versus content (for example, start-tag in title in head in html). |
|
抄送 Cv SGML → 验证 C-c C-v SGML → Validate |
sgml-验证 sgml-validate |
在迷你缓冲区中插入验证命令,以便您可以在按 Enter 执行之前根据需要对其进行修改。 Insert validation command in the minibuffer so you can modify it if necessary before pressing Enter to execute it. |
|
抄送 Ct SGML → 列出有效标签 C-c C-t SGML → List Valid Tags |
sgml 列表有效标签 sgml-list-valid-tags |
列出在当前上下文中有效的标签。 List tags that are valid in the current context. |
|
抄送 Cq 修改 → 填充元素 C-c C-q Modify → Fill Element |
sgml 填充元素 sgml-fill-element |
根据模式的缩进规则填充元素。 Fill element according to the mode's indentation rules. |
|
抄送共同 移动 → 下一个故障点 C-c C-o Move → Next Trouble Spot |
sgml 下一个问题点 sgml-next-trouble-spot |
找到下一个问题点并将问题显示在迷你缓冲区中。 Find the next problem spot and display the problem in the minibuffer. |
|
抄送 Cn 移动 → 向上元素 C-c C-n Move → Up Element |
sgml-up-元素 sgml-up-element |
移动到父元素。 Move to the parent element. |
|
抄送输入 C-c Enter |
sgml 分割元素 sgml-split-element |
分割当前元素。 Split current element. |
|
抄送 Cl SGML → 显示/隐藏警告日志 C-c C-l SGML → Show/Hide Warning Log |
sgml 显示或清除日志 sgml-show-or-clear-log |
显示或删除 Display or delete the |
|
抄送Ck 修改 → 取消标记 C-c C-k Modify → Kill Markup |
sgml 终止标记 sgml-kill-markup |
删除当前标签。 Delete current tag. |
|
抄送/ 标记 → 结束当前元素 C-c / Markup → End Current Element |
sgml 插入结束标签 sgml-insert-end-tag |
插入当前标签的结束标签。 Insert closing tag for current tag. |
|
抄送 - 修改 → 取消元素标签 C-c - Modify → Untag Element |
sgml-untag-元素 sgml-untag-element |
删除当前标签对。 Delete the current tag pair. |
|
Cc # 修改 → 制作字符参考 C-c # Modify → Make Character Reference |
sgml-make-字符-参考 sgml-make-character-reference |
将光标下的字符更改为等效实体。 Change character under the cursor to the equivalent entity. |
|
Cc Cf Ce 视图 → 折叠元素 C-c C-f C-e View → Fold Element |
sgml 折叠元素 sgml-fold-element |
隐藏当前元素及其子元素(如果有)。 Hide the current element and its children if any. |
|
Cc Cu Ce 视图 → 展开元素 C-c C-u C-e View → Unfold Element |
sgml-展开-元素 sgml-unfold-element |
显示当前元素及其子元素(如果有)。 Show the current element and its children if any. |
|
Cc Cf Cs 视图 → 折叠子元素 C-c C-f C-s View → Fold Subelement |
sgml 折叠子元素 sgml-fold-subelement |
隐藏子元素。 Hide subelements. |
|
Cc Cf Cr 视图 → 折叠区域 C-c C-f C-r View → Fold Region |
sgml 折叠区域 sgml-fold-region |
隐藏区域。 Hide the region. |
|
Cc Cu Ca 查看 → 全部展开 C-c C-u C-a View → Unfold All |
sgml-展开-全部 sgml-unfold-all |
显示所有隐藏的标签和文本。 Show all hidden tags and text. |
[ 9 ]我们要感谢 Emacs 大师 Eric Pement 向 Deb 推荐 TEI Emacs。
[9] We'd like to thank Emacs guru Eric Pement for pointing out TEI Emacs to Deb.
[ 10 ]我们真诚地希望这种支持也能扩展到 Mac OS X,为该平台上的开发人员和作者提供该工具功能的好处。同时,Mac 用户可能希望从http://thaiopensource.com/download/安装 nxml 模式,从http://www.lysator.liu.se/projects/about_psgml.html安装 psgml 模式。
[10] We sincerely hope that this support will be extended to Mac OS X as well, providing developers and writers on that platform the benefits of this tool's capabilities. Meanwhile, Mac users may want to install nxml mode from http://thaiopensource.com/download/ and psgml mode from http://www.lysator.liu.se/projects/about_psgml.html.
[ 11 ]有关为 psgml 模式设置完整环境的简单介绍,请访问http://openacs.org/doc/openacs-5-0-0/psgml-mode.html。
[11] A straightforward introduction to setting up a complete environment for psgml mode can be found at http://openacs.org/doc/openacs-5-0-0/psgml-mode.html.
GNU Emacs 为标记 TEX 文件提供了出色的支持。如今大多数人都使用 LATEX,它是用 TEX 编写的,可以更好地控制格式。因此,我们将在这里讨论 LaTeX 模式。
GNU Emacs provides excellent support for marking up TEX files. Most people today use LATEX , which is written in TEX and provides more control over formatting. As a result, we'll talk about LaTeX mode here.
在我们开始讨论之前,我们假设您已经在您的平台上设置了 LATEX。在 Red Hat Linux 上,它是默认设置的。 Windows 和 Mac OS X 用户必须先安装并配置 LATEX,然后才能继续。[ 12 ]
Before we launch into this discussion, we assume that you have set up LATEX on your platform. On Red Hat Linux, it's set up by default. Windows and Mac OS X users must install and configure LATEX before proceeding.[12]
Emacs 尝试猜测您正在编辑 TEX 还是 LATEX 文件并输入适当的模式。如果 Emacs 没有自动进入 LaTeX 模式,您可以通过键入Mx Latex-mode Enter来强制使用 LaTeX 模式。
Emacs attempts to guess whether you're editing a TEX or LATEX file and enter the appropriate mode. You can force LaTeX mode if Emacs doesn't enter it automatically by typing M-x latex-mode Enter.
LATEX 命令通常采用
表格
\keyword{text}。 LaTeX 模式不会尝试确定您是否使用了“正确”的关键字,因为该语言是可扩展的并且您可能已经定义了自己的关键字。然而,它确实为避免最常见的错误提供了支持:花括号和美元符号不匹配。
LATEX commands often take
the form
\keyword{text}. LaTeX mode
doesn't try to figure out if you're
using the "right" keywords since
the language is extensible and you may have defined your own
keywords. It does, however, provide support for avoiding the most
common error: mismatched curly braces and dollar signs.
在 LATEX 中,大括号 ({}) 和美元符号 ($$) 应始终成对出现; Emacs 检查以确保每个左大括号或美元符号都有对应的。当您键入右大括号或美元符号时,光标会快速移动到其对应位置(前提是它位于屏幕上;如果不在屏幕上,则会显示迷你缓冲区中的上下文),然后再次返回。
In LATEX , curly braces ({}) and dollar signs ($$) should always appear in pairs; Emacs checks to make sure that each opening brace or dollar sign has a counterpart. When you type a closing brace or dollar sign, the cursor moves quickly to its counterpart (provided that it is on the screen; it shows the context in the minibuffer if it is not), then back again.
Emacs 生成匹配对的大括号。命令Cc {插入左大括号和右大括号,并将光标定位在大括号之间以便键入。
Emacs generates braces in matching pairs. The command C-c { inserts opening and closing braces and positions the cursor for typing between the braces.
输入Cc }会使您越过右大括号。根据您当前的位置,它始终会找到正确的右大括号。如果没有右大括号,您会收到一条错误消息Scan error: Unbalanced
parentheses: 。如果您在光标位于未用大括号括起来的部分时键入Cc },也会收到此错误消息
,这可能会有点令人困惑。
Typing C-c } moves you past the
right brace. It always finds the correct closing brace, given your
current position. If there is no closing brace, you get an error
message that says Scan error: Unbalanced
parentheses. You also get this error message if you type
C-c } while the cursor is in a
section that is not surrounded by braces, which can be a little
confusing.
要检查是否有不匹配的花括号和美元符号,请输入Mx tex-validate-buffer Enter。该命令检查整个缓冲区中是否存在不平衡的括号、大括号、美元符号等。 (如果您有一个大文件,您可能需要验证一个区域,而不是使用Mx tex-validate-region Enter)。如果发现任何错误,Emacs 会显示一个顶部*Occur*带有 : 的缓冲区
Mismatches以及发现错误的行列表。然后,您可以使用Mx goto-line轻松移动到包含错误的每一行。
To check for mismatched curly braces and dollar signs, type M-x tex-validate-buffer Enter. This command
checks the entire buffer for unbalanced parentheses, curly braces,
dollar signs, and the like. (If you have a large file, you might want
to validate a region instead using M-x
tex-validate-region Enter). If it finds any errors, Emacs
displays an *Occur* buffer with
Mismatches: at the top and a list of lines on
which it found errors. You can then easily move to each line that
contains an error with M-x
goto-line.
有时,缓冲区早期不匹配的括号可能会在文件的其余部分启动“错误”的连锁反应。如果您怀疑所做的纠正之一可能已经修复了大部分剩余错误,只需再次运行 tex-validate-buffer即可。
Sometimes a mismatched parenthesis early in the buffer can start a chain reaction of "errors" through the rest of the file. If you suspect that one of the corrections you make may have fixed most of the remaining errors, simply run tex-validate-buffer again.
当您单步调试错误时,Cc }提供了一种检查给定左大括号的右大括号位置的好方法。将光标定位在左大括号后面并按Cc }。
When you're stepping through errors, C-c } provides a good way to check where the closing brace for a given opening brace is. Position the cursor right after the opening brace and press C-c }.
LaTeX 模式还具有以下功能 处理引号和段落分隔。输入引号 (") 会使 Emacs 模拟左引号和右引号。左引号表示为两个反引号字符 (``),而右引号表示为两个撇号 (' ')。(左引号和右引号不属于标准 ASCII 字符集。)如果出于任何原因需要键入文字引号,只需在引号前使用 quote-character 命令,如下所示: Cq ".
LaTeX mode also has features for handling quotation marks and paragraph separation. Typing a quotation mark (") causes Emacs to simulate left and right quotation marks. Left quotation marks are represented as two backtick characters (``) while right quotation marks are represented as two apostrophes (' '). (Left and right quotation marks are not part of the standard ASCII character set.) If you need to type a literal quotation mark for any reason, simply use the quote-character command preceding the quotation mark, like this: C-q ".
LaTeX 模式提供了支持 插入命令对。要插入命令对,请键入Cc Co(对于 Latex-insert-block)。 Emacs 提示输入块名称,然后提示输入关联选项。例如,键入Cc Co Enter document Enter Enter(第二个Enter表示没有选项)。 Emacs 插入命令对并将光标定位在它们之间:
LaTeX mode provides support for inserting command pairs. To insert a command pair, type C-c C-o (for latex-insert-block). Emacs prompts for the block name, and then for associated options. For example, type C-c C-o Enter document Enter Enter (the second Enter indicates no options). Emacs inserts the command pair and positions the cursor between them:
\开始{文档}
\结束{文档}\begin{document}
\end{document}您可以在写入文本文件后使用此命令对其进行标记。如果标记了一个区域,则可以键入Cc Co以在该区域周围包含一个命令对。
You can use this command to mark up a text file after you write it. If you mark a region, you can type C-c C-o to wrap a command pair around that region.
相关命令是Cc Ce(用于 Latex-close-block)。在这种情况下,您键入一个开始命令,然后按Cc Ce,Emacs 就会插入相应的结束命令。
A related command is C-c C-e (for latex-close-block). In this case, you type an opening command, press C-c C-e, and Emacs inserts the corresponding closing command.
这些命令适用于任何关键字,无论它是什么。 Emacs 无法检查以确保它是有效的 LATEX 关键字,甚至无法检查它是否已定义。例如,如果您输入\begin{eating} Cc Ce,Emacs 会插入 \end{eating}。您需要确保使用有效的关键字。
These commands work with any keyword, regardless of what it is. Emacs can't check to make sure that it's a valid LATEX keyword or even that it's been defined. For example, if you type \begin{eating} C-c C-e, Emacs inserts \end{eating}. It's up to you to make sure you use valid keywords.
除了标记文件之外
对于 LATEX ,您可以处理文件、查看错误(如果有)以及调用查看器,所有这些都无需离开 Emacs。要处理文件,只需键入
Cc Cf(对于tex-file)。[ 13 ] Emacs 在处理文件之前保存该文件。出现在屏幕上的消息被传送到一个名为 的缓冲区*tex-shell*,Emacs 将其显示在屏幕上。如果缓冲区不在屏幕上,则键入Cc Cl(对于
tex-recenter-output-buffer)会自动显示它。
In addition to marking up files
for LATEX
, you can process files, see your errors (if any), and invoke a
viewer, all without leaving Emacs. To process a file, just type
C-c C-f (for tex-file).[13] Emacs saves the file
before processing it. Messages that would appear on screen are
channeled to a buffer called *tex-shell*, which
Emacs displays on your screen. If the buffer isn't
on the screen, typing C-c C-l (for
tex-recenter-output-buffer)
automatically displays it.
为了演示,让我们尝试处理 dickens.tex,这确实是一个非常基本的文件。
To demonstrate, let's try processing dickens.tex, a very basic file indeed.
|
类型:CC Cf Type: C-c C-f |
|
|
|
处理 LATEX 文件会显示一个特殊的
Processing a LATEX file displays a special
|
此命令生成一个.dvi文件,它是一个独立于设备的中间文件。您可以通过键入Cc Cv查看结果文件。在 Linux 上,默认查看器是xdvi。按Cc Cv 将在xdvi窗口中显示输出 。
This command generates a .dvi file, which is an intermediate, device-independent file. You can view the resulting file by typing C-c C-v. On Linux, the default viewer is xdvi. Pressing C-c C-v displays the output in an xdvi window.
要打印.dvi文件,请输入命令 Cc Cp(对于tex-print);这将格式化 .dvi文件并将其发送到您的默认打印机。 Cc Cq ( tex-show-print-queue ) 显示打印队列,以便您知道何时前往打印机查找已处理的输出。
To print the .dvi file, give the command C-c C-p (for tex-print); this formats the .dvi file and sends it to your default printer. C-c C-q (tex-show-print-queue) displays the print queue so you know when to go to the printer to look for your processed output.
两个重要的变量告诉 Emacs 如何打印 TEX 文件。如果抄送 Cp 或抄送 Cq无法正常工作,您需要了解它们;如果这些命令不起作用,则您系统上的 TEX 配置可能不标准,或者打印和打印队列命令略有不同。变量 tex-dvi-print-command确定用于打印.dvi文件的命令;它的默认值是lpr -d。对于打印队列,用于显示打印队列的命令由 tex-show-queue-command变量控制。默认情况下,tex-show-queue-command设置为lpq。
Two important variables tell Emacs how to print a TEX , file. You need to know about them if C-c C-p or C-c C-q doesn't work correctly; if these commands don't work, the configuration of TEX , on your system may be nonstandard, or the print and print queue commands are slightly different. The variable tex-dvi-print-command determines the command that is used to print a .dvi file; its default is lpr -d. For print queues, the command used to show the print queue is controlled by the tex-show-queue-command variable. By default, tex-show-queue-command is set to lpq.
表 8-9总结了 TeX 和 LaTeX 模式命令。
Table 8-9 summarizes TeX and LaTeX mode commands.
表 8-9。 TeX 和 LaTeX 模式命令
Table 8-9. TeX and LaTeX mode commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
(没有任何) (none) |
文本模式 tex-mode |
根据文件内容进入TeX或LaTeX模式。 Enter TeX or LaTeX mode according to file's contents. |
|
(没有任何) (none) |
纯文本模式 plain-tex-mode |
进入 TeX 模式。 Enter TeX mode. |
|
(没有任何) (none) |
乳胶模式 latex-mode |
进入 LaTeX 模式。 Enter LaTeX mode. |
|
Cj C-j |
文本终止段落 tex-terminate-paragraph |
插入两个硬回车(段落的标准结尾)并检查段落的语法。 Insert two hard returns (standard end of paragraph) and check syntax of paragraph. |
|
抄送{ C-c { |
tex-插入-大括号 tex-insert-braces |
插入两个大括号并将光标放在它们之间。 Insert two braces and put cursor between them. |
|
抄送} C-c } |
上行列表 up-list |
如果位于大括号之间,请将光标定位在右大括号后面。 If you are between braces, position the cursor following the closing brace. |
|
(无)TeX → 验证缓冲区 (none)TeX → Validate Buffer |
tex 验证缓冲区 tex-validate-buffer |
检查缓冲区是否有语法错误。 Check buffer for syntax errors. |
|
(无)TeX → 验证区域 (none)TeX → Validate Region |
文本验证区域 tex-validate-region |
检查该区域是否存在语法错误。 Check the region for syntax errors. |
|
抄送 Cf TeX → TeX 文件 C-c C-f TeX → TeX File |
tex 文件 tex-file |
保存当前文件,然后对其进行处理。 Saves the current file, then processes it. |
|
抄送 Cb TeX → TeX 缓冲区 C-c C-b TeX → TeX Buffer |
文本缓冲区 tex-buffer |
处理缓冲区。[ 14 ] Process buffer.[14] |
|
抄送 Cl TeX → TeX 中心 C-c C-l TeX → TeX Recenter |
tex-recenter-输出缓冲区 tex-recenter-output-buffer |
将消息外壳放在屏幕上,显示(至少)最后一条错误消息。 Put the message shell on the screen, showing (at least) the last error message. |
|
抄送 Ck TeX → TeX Kill C-c C-k TeX → TeX Kill |
tex-kill-job tex-kill-job |
杀死处理。 Kill processing. |
|
抄送 Cp TeX → TeX 打印 C-c C-p TeX → TeX Print |
纺织印刷 tex-print |
打印输出。 Print output. |
|
抄送 Cq TeX → 显示打印队列 C-c C-q TeX → Show Print Queue |
tex 显示打印队列 tex-show-print-queue |
显示打印队列。 Show print queue. |
|
抄送CE C-c C-e |
乳胶封闭块 latex-close-block |
提供命令对的结束元素。 Provide closing element of a command pair. |
|
(没有任何) (none) |
tex-close-latex-块 tex-close-latex-block |
提供命令对的结束元素。 Provide closing element of a command pair. |
|
抄送选项卡` TeX → BibTeX 文件 C-c Tab` TeX → BibTeX File |
tex-bibtex-文件 tex-bibtex-file |
使用 BibTeX(一个自动创建参考书目的系统)处理当前文件。 Process the current file using BibTeX, a system for creating bibliographies automatically. |
|
抄送抄送 TeX → TeX 查看 C-c C-v TeX → TeX View |
文本视图 tex-view |
看法 。DVI输出。 View .dvi output. |
|
(无)TeX → TeX Print (替代打印机) (none)TeX → TeX Print (alt printer) |
文本替代打印 tex-alt-print |
使用变量tex-alt-dvi-print-command定义的备用打印机打印.dvi文件。 Print .dvi file using an alternative printer defined by the variable tex-alt-dvi-print-command. |
|
抄送公司 C-c C-o |
乳胶插入块 latex-insert-block |
插入块(提示输入块名称和选项)。 Insert a block (prompts for block name and options). |
|
铜铜 C-c C-u |
tex-goto-最后一个未封闭的乳胶块 tex-goto-last-unclosed-latex-block |
在文件中向后查找以找到最近的未闭合块并将光标移动到那里。 Look backward in the file to find the nearest unclosed block and move the cursor there. |
|
M-输入 M-Enter |
乳胶插入项目 latex-insert-item |
插入 Insert |
|
(没有任何) (none) |
乳胶分割块 latex-split-block |
插入当前块的结尾和新块的开头。 Insert an end to the current block and the beginning of a new one. |
|
” " |
文本插入引用 tex-insert-quote |
插入 TeX 样式的引号。 Insert TeX-style quotation marks. |
[ 12 ]本章前面提到的 TEI Emacs 会自动为您设置环境并添加更多功能,包括 Auctex,一个完整的创作环境,支持许多 TEX 变体以及用于生成参考书目的 bibcite/bibtex。然而,TEI Emacs 下的 LaTeX 模式似乎与 Emacs LaTeX 模式不同,我们在这里不做描述。
[12] TEI Emacs, mentioned earlier in this chapter, automatically sets up the environment for you and adds more features including Auctex, a complete authoring environment that supports many TEX variants as well as bibcite/bibtex for generating bibliographies. However, LaTeX mode under TEI Emacs appears to be a different beast from Emacs LaTeX mode, and we do not describe it here.
[ 13 ]如果你没有正确设置 TEX 环境(例如,Mac OS X 上并不是默认设置的),此命令会挂起或使 Emacs 崩溃(按Cg可能会有所帮助;在一位作者的情况下,确实如此)而在另一个则没有)。在尝试使用 Emacs 处理文件之前,请在 shell 提示符下尝试使用Latex命令来查看该命令是否存在。
[13] If you don't have your TEX environment set up properly (and it isn't by default on Mac OS X, for example), this command hangs or crashes Emacs (pressing C-g may help; in one author's case it did and in another's it didn't). Try the latex command at a shell prompt to see if the command exists before attempting to process a file using Emacs.
正如许多程序员所知,编程任务通常分为思考-编写-调试的循环。如果您使用 Unix(或各种其他操作系统)进行编程,您可能已经习惯于在周期的每个阶段使用单独的工具,例如用于编写的文本编辑器、用于编译的编译器以及操作系统本身用于运行程序。如果消除周期阶段以及支持它们的工具之间的界限,您无疑会发现一个更加高效的环境。
As many programmers know, the task of programming usually breaks down into a cycle of think-write-debug. If you have used Unix (or various other operating systems) for programming, you have probably become accustomed to using separate tools for each phase of the cycle, for example, a text editor for writing, a compiler for compiling, and the operating system itself for running programs. You would undoubtedly find an environment much more productive if the boundaries between the cycle phases—and the tools that support them—were erased.
Emacs 为编写、运行和调试用多种语言编写的程序提供了相当多的支持,并将这种支持集成到一个流畅的框架中。开发程序时您永远不必离开 Emacs,因此您会发现更容易专注于实际的编程任务(即循环的“思考”部分),因为您不必花费大量时间从一种工具开始到另一个。
Emacs provides considerable support for writing, running, and debugging programs written in a wide variety of languages, and it integrates this support into a smooth framework. You never have to leave Emacs when developing programs, so you will find it easier to concentrate on the actual programming task (i.e., the "think" part of the cycle) because you won't have to spend lots of time going from one tool to another.
当你编写代码时,你可以 使用 Emacs 的一种 编程语言模式;这些将 Emacs 变成了一个漂亮的语法导向或语言敏感的编辑器,它了解该语言的语法。这使您可以更轻松地以统一、易于阅读、可定制的风格编写代码。存在多种不同编程语言的语言模式。
When you write code, you can use one of Emacs's programming language modes; these turn Emacs into a spiffy syntax-directed or language-sensitive editor that knows about the syntax of the language. That makes it easier for you to write code in a uniform, easy-to-read, customizable style. Language modes exist for several different programming languages.
Emacs 还支持运行和调试程序。 Shell 模式(参见 第 5 章)和多个窗口(参见第 4 章)允许您在编辑代码时运行代码。 Emacs 具有强大的功能,可以连接许多编译器和 Unix make命令:Emacs 可以解释编译器的错误消息并访问在适当行号处发生错误的文件。事实上,许多工具(例如 Java 构建工具ant)都包含命令行选项,以 Emacs 友好的方式格式化其输出。
Emacs also supports running and debugging programs. Shell mode (see Chapter 5) and multiple windows (see Chapter 4) allow you to run your code while editing it. Emacs has a powerful facility for interfacing to many compilers and the Unix make command: Emacs can interpret compilers' error messages and visit files where errors occur at the appropriate line number. Indeed, many tools (such as the Java build tool, ant) include command-line options to format their output in an Emacs-friendly way.
在本章中,我们将介绍一般语言模式的功能,例如编译和调试程序、注释、缩进和语法突出显示。我们还花一些时间预先查看 etags工具,对于从事大型多文件项目的程序员来说是一个很大的帮助。这些功能适用于所有语言模式。然后我们深入研究 Emacs 对各种语言的支持,包括 C、C++、Java、Perl、SQL 和 Lisp。
In this chapter, we cover the features of language modes in general such as compiling and debugging programs, comments, indentation, and syntax highlighting. We also spend a bit of time upfront looking at the etags facility, which is a great help to programmers who work on large, multifile projects. These features apply to all language modes. We then delve into Emacs's support for various languages, including C, C++, Java, Perl, SQL, and Lisp.
Emacs 提供了一个许多吸引开发人员的功能。您可以通过字体支持以及函数和变量名称的自动完成功能快速编辑代码;您可以编译程序,甚至运行调试器,而无需离开“编辑器”。虽然您没有商业集成开发环境 (IDE) 中常见的一些图形工具,但这些 IDE 的几乎所有其他功能都可以在 Emacs 中找到,适用于您可以想象使用的每种语言。
Emacs provides a number of features that appeal to developers. You can edit code quickly with font support and auto-completion of function and variable names; you can compile the program and even run a debugger all without leaving your "editor." While you don't have some of the graphical tools commonly found in commercial integrated development environments (IDEs), almost every other feature of those IDEs can be found in Emacs—for every language you could imagine working in.
当然,有时您需要在没有某些语言模式附加的附加功能的情况下查看文档。您始终可以切换到纯文本 ( Mx text-mode ),或更重要的是,切换到基本模式 ( Mx basic-mode )。
Of course, there will always be occasions when you need to view your documents without the bells and whistles some language modes attach. You can always switch to plain text (M-x text-mode) or, more to the point, fundamental mode (M-x fundamental-mode).
正如提到的 从本章开始,Emacs 对程序员的支持并没有随着代码的编写而结束。在处理大型编程项目时使用 Emacs 的典型策略是登录,转到源文件所在的目录,然后在源文件上调用 Emacs(例如,对于 C 程序员,emacs Makefile myproj*.[ch] ) 。当您编辑代码时,您可以使用稍后描述的命令对其进行编译 - 正如您将看到的,您甚至无需担心保存更改。您还可以使用 shell 模式在 shell 中测试编译后的代码(请参阅第 5 章)。最重要的是,您应该很少(如果有的话)在整个会话过程中必须离开 Emacs。
As mentioned at the beginning of this chapter, Emacs's support for programmers does not end when you are done writing the code. A typical strategy for using Emacs when working on a large programming project is to log in, go to the directory where your source files reside, and invoke Emacs on the source files (e.g., emacs Makefile myproj*.[ch] for C programmers). While you are editing your code, you can compile it using the commands described later—as you will see, you need not even worry about saving your changes. You can also test your compiled code in a shell using shell mode (see Chapter 5). The bottom line is that you should rarely—if ever—have to leave Emacs throughout your session.
Emacs提供了一个界面 编译器和 Unix make实用程序比 shell 模式更直接、更强大。该工具的核心是命令 MxcompileEnter。该命令会导致一系列事件发生。首先,它会提示您输入编译命令。默认命令是make -k , [ 1 ],但如果您键入另一个命令,该新命令将成为 Emacs 会话期间后续调用的默认命令。您可以通过在 .emacs文件中设置变量compile-command来更改默认值。例如,要使用 Java 构建工具ant作为默认编译命令,只需添加以下行:
Emacs provides an interface to compilers and the Unix make utility that is more direct and powerful than shell mode. At the heart of this facility is the command M-x compile Enter. This command causes a series of events to occur. First, it prompts you for a compilation command. The default command is make -k,[1] but if you type another command, that new command becomes the default for subsequent invocations during your Emacs session. You can change the default by setting the variable compile-command in your .emacs file. For example, to use the Java build tool ant as your default compile command, just add this line:
(setq '编译命令“ant -emacs”)
(setq 'compile-command "ant -emacs")
输入命令后,Emacs 会保存所有未保存的文件缓冲区,从而免除您确保更改已保存的责任。然后它创建一个名为 的缓冲区
*compilation*和一个关联的窗口。它运行编译命令(作为子进程,就像 shell 模式下的 shell),并将输出发送到缓冲区
*compilation*。当命令运行时,迷你缓冲区显示Compiling: run;它表示
exit编译作业何时完成。
After you have typed the command, Emacs offers to save all unsaved
file buffers, thus relieving you of the responsibility of making sure
your changes have been saved. It then creates a buffer called
*compilation* and an associated window. It runs
the compilation command (as a subprocess, just like the shell in
shell mode), with output going to the
*compilation* buffer. While the command runs, the
minibuffer says Compiling: run; it says
exit when the compile job finishes.
现在乐趣开始了。如果编译导致错误,您可以键入Cx `(对于next-error;这是反引号,而不是单引号)。 Emacs 读取第一条错误消息,找出错误的文件和行号,然后访问该行号处的文件。更正错误后,您可以再次键入Cx `以访问后续错误位置。每次键入Cx `时,Emacs 都会滚动*compilation*窗口,以便当前错误消息显示在顶部。
Now the fun begins. If the compilation resulted in an error, you can
type C-x ` (for next-error; this is a backquote, not a single
quote). Emacs reads the first error message, figures out the file and
line number of the error, and visits the file at that line number.
After you have corrected the error, you can type C-x ` again to visit subsequent error
locations. Each time you type C-x `,
Emacs scrolls the *compilation* window so that the
current error message appears at the top.
要再次从第一条错误消息开始,请键入带有前缀参数的Cx ` (即Cu Cx `)。Cx `的一个好处是,一旦遇到错误就可以使用它;您不必等待编译完成。
To start at the first error message again, type C-x ` with a prefix argument (i.e., C-u C-x `). A nice thing about C-x ` is that you can use it as soon as an error is encountered; you do not have to wait for the compilation to finish.
缓冲区模式*compilation*(编译模式)支持一些其他有用的命令,用于浏览错误消息,如表 9-1中总结的那样。
The mode of the *compilation* buffer (compilation
mode) supports a few other useful commands for navigating through the
error messages as summarized in Table 9-1.
表 9-1。编译模式命令
Table 9-1. Compilation mode commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CX` C-x ` |
下一个错误 next-error |
转到下一条错误消息并访问相应的源代码。 Move to the next error message and visit the corresponding source code. |
|
锰 M-n |
编译下一个错误 compilation-next-error |
移至下一条错误消息。 Move to the next error message. |
|
熔点 M-p |
编译前一个错误 compilation-previous-error |
移至上一条错误消息。 Move to the previous error message. |
|
抄送抄送 C-c C-c |
编译转到错误 compilation-goto-error |
访问当前错误消息的源代码。 Visit the source code for the current error message. |
|
空间 Space |
向下滚动 scroll-down |
向下滚动一屏。 Scroll down one screen. |
|
德尔 Del |
向上滑动 scroll-up |
向上滚动一屏。 Scroll up one screen. |
Space和Del是在各种只读 Emacs 模式中使用的方便的屏幕滚动命令。
Space and Del are handy screen-scrolling commands found in various read-only Emacs modes.
注意Mn和Mp不访问错误信息对应的源代码;它们只是让您轻松地浏览可能占用多行的错误消息。但是,您可以通过键入Cc Cc从任何错误消息访问源代码。
Note that M-n and M-p do not visit the source code corresponding to the error message; they simply allow you to move easily through error messages that may take up more than one line each. However, you can visit the source code from any error message by typing C-c C-c.
Emacs如何解释 错误信息?它使用变量compilation-error-regexp-alist,它是一个正则表达式列表,旨在匹配各种C和C++编译器以及lint C代码检查程序的错误消息。[ 2 ]它还应该与 Emacs 具有语言模式的语言的编译器一起使用,例如 Java、Fortran、Ada 和 Modula-2。 Emacs 尝试使用列表中的每个正则表达式来解析(分析)错误消息,直到找到一个能够提取发生错误的文件名和行号的表达式。
How does Emacs interpret the error message? It uses the variable compilation-error-regexp-alist, which is a list of regular expressions designed to match the error messages of a wide variety of C and C++ compilers and the lint C code checking program.[2] It should also work with compilers for languages for which Emacs has language modes, such as Java, Fortran, Ada, and Modula-2. Emacs tries to parse (analyze) an error message with each of the regular expressions in the list until it finds one that extracts the filename and line number where the error occurred.
有可能会出现这个错误
消息解析器无法与某些编译器一起工作,特别是当您在非 Unix 系统上使用 Emacs 时。您可以通过尝试Mx 编译一些您知道包含错误的代码来找出答案;如果您输入Cx `,并且 Emacs 声称存在no more errors,则下一个错误功能不适用于您的编译器。
There is a chance that the error
message parser won't
work with certain compilers, especially if you are using Emacs on a
non-Unix system. You can find out by trying M-x
compile on some code that you know contains an error; if
you type C-x `, and Emacs claims
that there are no more errors, the next-error feature does not work with your
compiler.
如果解析器不适合您,您可能需要尝试向compilation-error-regexp-alist添加一个适合您的编译器错误消息格式的正则表达式。我们将在第 11 章中向您展示一个例子。
If the parser doesn't work for you, you may want to try adding a regular expression to compilation-error-regexp-alist that fits your compiler's error message format. We'll show you an example of this in Chapter 11.
编译包也 包括对 Unix grep (搜索文件)命令的类似支持,从而有效地为 Emacs 提供了多文件搜索功能。如果您输入Mx grep,系统会提示您输入要发送到grep 的参数,即搜索模式和文件名。 Emacs使用-n选项运行grep,该选项告诉它打印文件名和匹配行的行号。[ 3 ]与Mx 编译的情况相同;您可以输入Cx `让 Emacs 访问其文件中的下一个匹配行。
The compile package also includes similar support for the Unix grep (search files) command, thus effectively giving Emacs a multifile search capability. If you type M-x grep, you are prompted for arguments to send to grep—that is, a search pattern and filename(s). Emacs runs grep with the -n option, which tells it to print filenames and line numbers of matching lines.[3] The same happens as with M-x compile; you can type C-x ` to have Emacs visit the next matched line in its file.
[ 1 ] -k选项覆盖make在作业返回错误后停止的默认设置。相反,make 会在依赖关系树的不依赖于发生错误的分支的分支上继续执行。
[1] The -k option overrides make's default of stopping after a job returns an error. Instead, make continues on branches of the dependency tree that do not depend on the branch where the error occurred.
我们已经看到了 Emacs 模式的各种示例,包括文本模式(参见第 2 章)和 shell 模式(参见第 5 章)。像缓冲区列表(参见第 4 章)和 Dired(参见第 5 章)这样的特殊功能实际上也是模式。所有模式都有两个基本组件:实现该模式的Emacs Lisp包和调用该模式的函数。
We have already seen various examples of Emacs modes, including text mode (see Chapter 2) and shell mode (see Chapter 5). Special functionality like the buffer list (see Chapter 4) and Dired (see Chapter 5) are actually modes as well. All modes have two basic components: an Emacs Lisp package that implements the mode and a function that invokes it.
Emacs 版本 哪个 本书基于(21.3.5)附带的语言模式为Ada、汇编、awk、C、C++、Common Lisp、Fortran、ICON、Java、Lisp、MIM、Modula-2、Objective-C、Pascal、Pike、Perl 、PROLOG、Python、Scheme、SGML、Simula 和 SQL;未来的版本无疑会添加更多。许多(但不是全部)语言模式都“挂钩”到 Emacs 中,因此如果您访问具有正确文件名后缀的文件,您将自动进入正确的模式。要了解 Emacs 是否对您使用的语言执行此操作,请在附录 B 中的 Emacs Lisp 软件包表中查找您的语言。如果右侧列中列出了一个或多个后缀,则 Emacs 会调用具有这些后缀的文件的模式后缀。
The version of Emacs on which this book is based (21.3.5) comes with language modes for Ada, assembly, awk, C, C++, Common Lisp, Fortran, ICON, Java, Lisp, MIM, Modula-2, Objective-C, Pascal, Pike, Perl, PROLOG, Python, Scheme, SGML, Simula, and SQL; future versions will undoubtedly add more. Many—but not all—of the language modes are "hooked" into Emacs so that if you visit a file with the proper filename suffix, you will automatically be put in the correct mode. To find out whether Emacs does this for the language you use, look up your language in the table of Emacs Lisp packages in Appendix B. If one or more suffixes is listed in the right-hand column, Emacs invokes the mode for files with those suffixes.
但是,如果未列出后缀(或者您的编译器支持与所列出的后缀不同的后缀),您可以将 Emacs 设置为在访问源文件时自动调用该模式。您需要做两件事:首先,再次查看您的语言的包表条目中的右侧列,您将找到调用模式的函数的名称(例如ada-mode、modula-2-模式)。其次,在.emacs文件中插入代码,告诉 Emacs 在您访问带有相关语言后缀的文件时自动加载正确的包。
However, if no suffix is listed (or if your compiler supports a different suffix than the ones listed), you can set up Emacs to invoke the mode automatically when you visit your source files. You need to do two things: first, look again at the right-hand column in the package table entry for your language, and you will find the name of the function that invokes the mode (e.g., ada-mode, modula-2-mode). Second, you insert code in your .emacs file that tells Emacs to automatically load the proper package whenever you visit a file with the suffix for the language in question.
您需要为此自定义编写两行代码。第一个使用自动加载功能,它告诉 Emacs 在哪里寻找它还不知道的命令。它在函数和实现该函数的包之间建立关联,以便在第一次调用该函数时,Emacs 加载该包以获取代码。在我们的例子中,我们需要在调用语言模式的函数和实现该模式的包之间创建关联。这显示了自动加载的格式:
You need to write two lines of code for this customization. The first uses the autoload function, which tells Emacs where to look for commands it doesn't already know about. It sets up an association between a function and the package that implements the function so that when the function is invoked for the first time, Emacs loads the package to get the code. In our case, we need to create an association between a function that invokes a language mode and the package that implements the mode. This shows the format of autoload:
(自动加载'function“filename”“description”t)
(autoload 'function"filename""description" t)
请注意前面的单引号以及and
function周围的双引号;有关此 Lisp 语法的更多详细信息,请参阅第 11 章。例如,如果您是 PHP 程序员,您可以从http://sourceforge.net/projects/php-mode/
在线获取最新的 Emacs PHP 模式。然后,您可以将以下行放入
.emacs文件中:filenamedescription
Note the single quote preceding function and the
double quotes around filename and
description; for more details on this Lisp syntax,
see Chapter 11. If you are a PHP programmer, for
example, you can grab the latest Emacs PHP mode from http://sourceforge.net/projects/php-mode/
online. You would then put the following line in your
.emacs file:
(autoload 'php-mode "php-mode" "PHP 编辑模式。" t)
(autoload 'php-mode "php-mode" "PHP editing mode." t)
这告诉 Emacs 在第一次调用php-mode函数时加载PHP包。
This tells Emacs to load the PHP package when the function php-mode is invoked for the first time.
第二行代码通过在您的语言的源文件后缀和模式调用函数之间创建关联来完成整个图片,以便当您访问具有正确后缀的文件时自动调用该函数。这涉及到 Emacs 全局变量auto-mode-alist,将在第 10 章中介绍;它是 Emacs 用来根据文件名称将访问过的文件置于模式中的关联列表。要为 PHP 模式创建这样的关联,以便 Emacs 将所有带有后缀.php 的文件置于该模式中,请将此行添加到您的.emacs文件中:
The second line of code completes the picture by creating an association between the suffix for source files in your language and the mode-invoking function so that the function is automatically invoked when you visit a file with the proper suffix. This involves the Emacs global variable auto-mode-alist, covered in Chapter 10; it is a list of associations that Emacs uses to put visited files in modes according to their names. To create such an association for PHP mode so that Emacs puts all files with the suffix .php in that mode, add this line to your .emacs file:
(setq 自动模式列表 (cons '("\\.php$" .php-mode) 自动模式列表))(setq auto-mode-alist (cons '("\\.php$" . php-mode) auto-mode-alist))当您访问其后缀表示您的编程语言的源代码的文件时,此 Lisp 代码将设置以下事件链。假设您访问文件 pgm.php。 Emacs 读取该文件,然后在 auto-mode-alist中找到与.php后缀对应的条目,并尝试调用关联的函数php-mode。它注意到函数php-mode不存在,但它和PHP包之间 存在自动加载关联。它加载该包并找到php-mode命令并运行它。之后,您的缓冲区就处于 PHP 模式。
This Lisp code sets up the following chain of events when you visit a file whose suffix indicates source code in your programming language. Let's say you visit the file pgm.php. Emacs reads the file, then finds an entry corresponding to the .php suffix in the auto-mode-alist and tries to invoke the associated function php-mode. It notices that the function php-mode doesn't exist, but that there is an autoload association between it and the PHP package. It loads that package and, finding the php-mode command, runs it. After this, your buffer is in PHP mode.
对于某些解释性语言(例如 Perl 和 Python),您还需要更新解释器模式 alist 全局变量:
For some interpreted languages like Perl and Python, you will also want to update the interpreter-mode-alist global variable:
(setq 解释器模式列表
(cons '("python" . python-mode)
解释器模式列表))(setq interpreter-mode-alist
(cons '("python" . python-mode)
interpreter-mode-alist))如果您的脚本文件以 Unix 解释器前缀#!,Emacs 检查该行以确定您正在使用什么语言。当脚本文件没有像 .py或.pl这样的明显扩展名时,这尤其有用。
If your script file begins with the Unix interpreter prefix #!, Emacs checks that line to determine what language you are using. That can be especially helpful when the script file does not have a telltale extension like .py or .pl.
尽管语言模式在具体上有所不同 功能,它们都支持相同的基本概念。其中最重要的是对所讨论语言的语法的了解——它的字符、词汇和语法的某些方面。我们已经看到 Emacs 处理人类语言的一些语法方面。当您编辑常规文本时,Emacs 知道单词、句子和段落:您可以移动光标并删除与这些单位相关的文本。它还知道某些类型的标点符号,例如括号:当您键入右括号时,它会通过将光标移到那里一秒钟然后返回来“闪烁”匹配的左括号。[ 4 ]这是确保括号正确匹配的便捷方法。
Although language modes differ in exact functionality, they all support the same basic concepts. The most important of these involves knowledge of the syntax of the language in question—its characters, vocabulary, and certain aspects of its grammar. We have already seen that Emacs handles some syntactic aspects of human language. When you edit regular text, Emacs knows about words, sentences, and paragraphs: you can move the cursor and delete text with respect to those units. It also knows about certain kinds of punctuation, such as parentheses: when you type a right parenthesis, it "flashes" the matching left parenthesis by moving the cursor there for a second and then returning.[4] This is a convenient way of ensuring that your parentheses match correctly.
Emacs 具有有关编程语言语法的知识,这类似于其对人类语言语法的了解。一般来说,它跟踪以下基本语法元素:
Emacs has knowledge about programming language syntax that is analogous to its knowledge of human language syntax. In general, it keeps track of the following basic syntactic elements:
单词,对应于 大多数编程语言中的标识符和数字。
Words, which correspond to identifiers and numbers in most programming languages.
标点符号,包括 运算符(例如+、 -、 <和>)和语句分隔符(例如分号)等内容。
Punctuation, which includes such things as operators (e.g., +, -, <, and >) and statement separators (e.g., semicolons).
Strings,是按字面意思理解并用分隔符 (例如引号)括起来的字符串。
Strings, which are strings of characters to be taken literally and surrounded by delimiters (such as quotation marks).
括号,可以包括方括号( [和])和大括号( {和})以及常规括号等内容
Parentheses, which can include such things as square brackets ([ and ]) and curly braces ({ and }) as well as regular parentheses.
空白,例如空格和制表符,将被忽略。
Whitespace, such as spaces and tabs, which are to be ignored.
评论,其中 要忽略的字符串,并由取决于语言的分隔符包围(例如,C 中的/*和*/ , C++ 和 Java 中的 // 和换行符,或者Lisp 中的分号( ; ) 和换行符)。
Comments, which are strings of characters to be ignored and surrounded by delimiters that depend on the language (e.g., /* and */ for C, // and a newline for C++ and Java, or semicolon (;) and a newline for Lisp).
Emacs 在内部以语法表的形式保存这些信息 ;与键盘映射(如第 10 章所述 )一样,Emacs 有一个 用于所有缓冲区的全局语法表,以及每个缓冲区的本地表,该表根据缓冲区所处的模式而变化。您可以查看当前缓冲区的语法表。通过输入Ch s(用于描述语法)来缓冲。此外,语言模式还了解更高级的依赖于语言的语法概念,如语句、语句块、函数、子例程、Lisp 语法表达式等。
Emacs keeps this information internally in the form of syntax tables; like keymaps (as described in Chapter 10), Emacs has a global syntax table used for all buffers, as well a local table for each buffer, which varies according to the mode the buffer is in. You can view the syntax table for the current buffer by typing C-h s (for describe-syntax). In addition, language modes know about more advanced language-dependent syntactic concepts like statements, statement blocks, functions, subroutines, Lisp syntactic expressions, and so on.
所有编程 语言有注释语法,因此 Emacs 提供了一些一般处理注释的功能;这些在每种语言模式中都是特定于语言的。所有语言模式的通用注释命令是M-;(用于缩进注释)。[ 5 ]当您输入M- 时; ,Emacs 移动到等于变量comment-column值的列;如果该行上的文本超过该列,它将移动到最后一个文本字符之后的一个空格。然后,它插入一个注释分隔符(或一对开始和结束分隔符,如 C 的 /* 和 */),并将光标放在开始分隔符之后。
All programming languages have comment syntax, so Emacs provides a few features that deal with comments in general; these are made language-specific in each language mode. The universal comment command for all language modes is M-; (for indent-for-comment).[5] When you type M-;, Emacs moves to a column equal to the value of the variable comment-column; if the text on the line goes past that column, it moves to one space past the last text character. It then inserts a comment delimiter (or a pair of opening and closing delimiters, as in /* and */ for C) and puts the cursor after the opening delimiter.
例如,如果要向语句添加注释,请将光标放在包含该语句的行上的任意位置并键入 M-;。结果是
For example, if you want to add a comment to a statement, put the cursor anywhere on the line containing that statement and type M-;. The result is
结果+= y; /* */
result += y; /* */
然后,您可以在分隔符之间输入您的注释。如果您要在较长的代码行上执行相同的操作,例如,
You can then type your comment in between the delimiters. If you were to do the same thing on a longer line of code, say,
q_i = term_arr[i].num_docs /total_docs;
q_i = term_arr[i].num_docs / total_docs;
结果将是
the result would be
q_i = term_arr[i].num_docs /total_docs; /* */
q_i = term_arr[i].num_docs / total_docs; /* */
当然,您可以通过将适当的代码放入.emacs文件中来自定义变量comment-column。如果您想永久这样做,这是最有用的方法。但是,如果您想在当前缓冲区内临时重置注释列,只需将光标移动到您想要注释列的位置并输入Cx 即可;(对于设置评论列)。注意该命令只影响当前缓冲区中comment-column的值;它在其他缓冲区中的值(甚至相同模式下的其他缓冲区)不会改变。
You can customize the variable comment-column, of course, by putting the appropriate code in your .emacs file. This is the most useful way if you want to do it permanently. But if you want to reset comment-column temporarily within the current buffer, you can just move the cursor to where you want the comment column to be and type C-x ; (for set-comment-column). Note that this command affects only the value of comment-column in the current buffer; its value in other buffers—even other buffers in the same mode—is not changed.
当您输入注释并希望在下一行继续时,Mj(用于indent-new-comment-line)会执行此操作。此命令在下一行开始一个新注释(尽管某些语言模式允许您对其进行自定义,以便它继续相同的注释)。假设您已输入此语句的注释文本,并且光标位于文本末尾:
When you are typing a comment and want to continue it on the next line, M-j (for indent-new-comment-line) does it. This command starts a new comment on the next line (though some language modes allow you to customize it so that it continues the same comment instead). Say you have typed in the text of the comment for this statement, and the cursor is at the end of the text:
结果+=y; /* 被乘数相加 */
result += y; /* add the multiplicand */
您想将注释扩展到另一行。如果您输入Mj,您会得到以下内容:
You want to extend the comment to another line. If you type M-j, you get the following:
结果+=y; /* 添加被乘数*/
/* * / result += y; /* add the multiplicand*/
/* */您可以输入评论的第二行。您还可以使用 Mj将现有注释文本拆分为两行。假设您的光标定位如下:
You can type the second line of your comment. You can also use M-j to split existing comment text into two lines. Assume your cursor is positioned like this:
结果+=y; /* 被乘数相加 */
result += y; /* add the multiplicand */
如果您现在输入Mj,结果是:
If you type M-j now, the result is:
结果+=y; /* 添加 */
/* m被数 */ result += y; /* add the */
/* multiplicand */如果要注释掉代码的一部分,可以使用 comment-region命令(除某些语言模式外,不受击键限制)。假设您的代码如下所示:
If you want to comment out a section of your code, you can use the comment-region command (not bound to keystrokes except in certain language modes). Assume you have code that looks like this:
这=是(a);
(源代码)部分;
that += (需要[up]->一个 * 数字);
(行); this = is (a);
section (of, source, code);
that += (takes[up]->a * number);
of (lines);如果您以通常的方式定义一个区域并输入Mx comment-region,结果是:
If you define a region in the usual way and type M-x comment-region, the result is:
/* 这 = 是 (a); */ /* 部分(源代码); */ /* that += (需要[up]->一个*数字); */ /*(行); */
/* this = is (a); */ /* section (of, source, code); */ /* that += (takes[up]->a * number); */ /* of (lines); */
您可以通过输入Mx Kill-comment Enter轻松删除单行注释,这会删除当前行上的任何注释。光标不必位于注释内。每种语言模式都有与特定语言的评论相关的特殊功能,通常包括可让您自定义评论风格的变量。
You can easily get rid of single-line comments by typing M-x kill-comment Enter, which deletes any comment on the current line. The cursor does not have to be within the comment. Each language mode has special features relating to comments in the particular language, usually including variables that let you customize commenting style.
除了句法知识之外, Emacs 语言模式包含各种功能来帮助您生成格式良好的代码。这些功能实现了缩进、注释和编程风格其他方面的标准,从而确保一致性和可读性、使注释对齐等等。也许更重要的是,它们减轻了您提供正确缩进甚至记住当前缩进是什么的繁琐负担。这些标准最好的一点是它们通常是可定制的。
In addition to syntactic knowledge, Emacs language modes contain various features to help you produce nicely formatted code. These features implement standards of indentation, commenting, and other aspects of programming style, thus ensuring consistency and readability, getting comments to line up, and so on. Perhaps more importantly, they relieve you of the tiresome burden of supplying correct indentation and even of remembering what the current indentation is. The nicest thing about these standards is that they are usually customizable.
我们已经看到,在文本模式下,您可以在行尾键入Cj而不是Enter ,Emacs 会为您正确缩进下一行。此缩进由变量left-margin控制,其值是要缩进的列。在编程语言模式中也会发生很多相同的事情,但过程更加灵活和复杂。
We have already seen that, in text mode, you can type C-j instead of Enter, at the end of a line, and Emacs indents the next line properly for you. This indentation is controlled by the variable left-margin, whose value is the column to indent to. Much the same thing happens in programming language modes, but the process is more flexible and complex.
与文本模式一样,Cj在语言模式下正确缩进下一行。键入任何行后,您还可以通过将光标放在行上的任意位置按Tab键来正确缩进。
As in text mode, C-j indents the next line properly in language modes. You can also indent any line properly after it has been typed by pressing Tab with the cursor anywhere on the line.
某些语言模式具有附加到终止语句的字符(例如分号或右大括号)的额外功能,因此当您键入它们时,Emacs 会自动缩进当前行。 Emacs 文档将这种行为称为 “电动”。大多数语言模式还具有控制缩进样式(并且您可以自定义)的变量集。
Some language modes have extra functionality attached to characters that terminate statements—like semicolons or right curly braces—so that when you type them, Emacs automatically indents the current line. Emacs documentation calls this behavior electric. Most language modes also have sets of variables that control indentation style (and that you can customize).
表 9-2列出了一些与缩进相关的其他命令,这些命令根据为该语言设置的规则起作用 有问题。
Table 9-2 lists a few other commands relating to indentation that work according to the rules set up for the language in question.
表 9-2。基本缩进命令
Table 9-2. Basic indentation commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
厘米-\ C-M-\ |
缩进区域 indent-region |
缩进光标和标记之间的每一行。 Indent each line between the cursor and mark. |
|
毫米 M-m |
回到缩进 back-to-indentation |
移至该行的第一个非空白字符。 Move to the first nonblank character on the line. |
|
M-^ M-^ |
删除缩进 delete-indentation |
将此行连接到上一行。 Join this line to the previous one. |
以下是CM-\功能的示例。这个例子是C语言的,后续的例子都会参考它。本节所有示例中的概念适用于大多数其他语言;我们在这些语言的模式部分中介绍了类似的 Lisp 和 Java 功能。
The following is an example of what C-M-\ does. This example is in C, and subsequent examples refer to it. The concepts in all examples in this section are applicable to most other languages; we cover analogous Lisp and Java features in the sections on modes for those languages.
假设您有以下 C 代码:
Suppose you have the following C code:
整数倍 (x, y)
整数x,y;
{
整数我;
整数结果 = 0;
对于 (i = 0; i < x; i++)
{
结果+=y;
}
}int times (x, y)
int x, y;
{
int i;
int result = 0;
for (i = 0; i < x; i++)
{
result += y;
}
}如果您在这段代码的开头设置了标记,将光标放在末尾,然后输入CM-\,Emacs 将其格式化如下:
If you set mark at the beginning of this code, put the cursor at the end, and type C-M-\, Emacs formats it like this:
整数倍 (x, y)
整数x,y;
{
整数我;
整数结果 = 0;
对于 (i = 0; i < x; i++)
{
结果+= y;
}
}int times (x, y)
int x, y;
{
int i;
int result = 0;
for (i = 0; i < x; i++)
{
result += y;
}
}CM-\也可以方便地根据您的特定缩进样式缩进整个文件:您只需键入Cx h(用于mark-whole-buffer),然后键入CM-\。
C-M-\ is also handy for indenting an entire file according to your particular indentation style: you can just type C-x h (for mark-whole-buffer) followed by C-M-\.
Mm可以方便地移动到一行中实际代码的开头。例如,假设您的光标定位如下:
M-m is handy for moving to the beginning of the actual code on a line. For example, assume your cursor is positioned like this:
整数结果t = 0; int result = 0;如果您输入Mm ,它将移动到int的开头:
If you type M-m, it moves to the beginning of the int:
i nt 结果 = 0; int result = 0;作为M-^的示例,假设您希望 for语句的左大括号与for出现在同一行。将光标放在带有左大括号的行上的任意位置,键入M-^,代码如下所示:
As an example of M-^, let's say you want the opening curly brace for the for statement to appear on the same line as the for. Put the cursor anywhere on the line with the opening curly brace, type M-^, and the code looks like this:
for (i = 0; i < x; i++) {
结果+= y;
} for (i = 0; i < x; i++) {
result += y;
}语言模式通常提供与语言的特定功能相关的附加缩进命令。介绍了通用语言模式概念后,我们想向您展示一些其他通用实用程序:etag和字体锁定模式。etags工具可以帮助从事大型多文件程序的程序员。所有语言模式都可以利用字体锁定模式,使开发更加高效。
Language modes usually provide additional indentation commands that relate to specific features of the language. Having covered the general language mode concepts, we want to show you a few other general utilities: etags and font-lock mode. The etags facility helps programmers who work on large, multifile programs. All language modes can also take advantage of font-lock mode to make development more efficient.
另一个普遍特征是 适用于程序员的 Emacs 是etags 工具。[ 6 ] etags也适用于许多其他语言的代码,包括 Fortran、Java、Perl、Pascal、LATEX、Lisp 和许多汇编语言。如果您从事大型多文件项目,您会发现etag提供了巨大的帮助。
Another general feature of Emacs that applies to programmers is the etags facility.[6] etags works with code in many other languages as well, including Fortran, Java, Perl, Pascal, LATEX,, Lisp, and many assembly languages. If you work on large, multifile projects, you will find etags to be an enormous help.
etags基本上是一个多文件搜索工具了解 C 和 Perl 函数定义以及一般搜索。有了它,您可以在整个目录中的任何位置找到函数,而不必记住该函数是在哪个文件中定义的,并且您可以跨多个文件进行搜索和查询替换。etags使用 标记表,其中包含目录中每个文件的函数名称列表以及有关函数定义在文件中的位置的信息。许多与etag相关的命令都涉及搜索字符串中的正则表达式(请参阅第 11 章)。
etags is basically a multifile search facility that knows about C and Perl function definitions as well as searching in general. With it, you can find a function anywhere in an entire directory without having to remember in which file the function is defined, and you can do searches and query-replaces that span multiple files. etags uses tag tables, which contain lists of function names for each file in a directory along with information on where the functions' definitions are located within the files. Many of the commands associated with etags involve regular expressions (see Chapter 11) in search strings.
要使用etags,您必须首先在当前目录中调用单独的etags程序来创建标记表。它的参数是您想要其标签信息的文件。调用它的常用方法是etags *.[ch],即从所有以.c或 .h结尾的文件构建标签表。 (这适用于 C 程序员;当然,其他语言会使用它们适当的扩展。)您可以从 shell 模式或使用命令M-!运行etags。 (对于shell 命令)。etags的输出 是文件 TAGS,它是标签表。当您编写代码时,您可以通过再次调用etags来更新标记表以反映新文件和函数定义。
To use etags, you must first invoke the separate etags program in your current directory to create the tag table. Its arguments are the files for which you want tag information. The usual way to invoke it is etags *.[ch], that is, building a tag table from all files ending in .c or .h. (That's for you C programmers; other languages would use their appropriate extensions, of course.) You can run etags from shell mode or with the command M-! (for shell-command). The output of etags is the file TAGS, which is the tag table. When you are writing code, you can update your tag table to reflect new files and function definitions by invoking etags again.
创建标签表后,您需要让 Emacs 知道它。为此,请输入Mx Visit-tags-table Enter。这会提示您输入标签表文件的名称;正如您所期望的,默认值是当前目录中的TAGS 。执行此步骤后,您可以使用各种 Emacs 标签命令。
After you have created the tag table, you need to make it known to Emacs. To do this, type M-x visit-tags-table Enter. This prompts you for the name of the tag table file; the default is TAGS in the current directory, as you would expect. After you execute this step, you can use the various Emacs tags commands.
最重要的标签命令是M-。 (对于查找标签)。此命令提示您输入一个字符串,用于在标签表中搜索名称包含该字符串的函数。提供搜索字符串,Emacs 就会访问当前窗口中包含匹配函数名称的文件,并转到函数定义的第一行。M-的变体。是Cx 4。 (对于find-tag-other-window),它使用另一个窗口而不是替换当前窗口中的文本。
The most important tag command is M-. (for find-tag). This command prompts you for a string to use in searching the tag table for a function whose name contains the string. Supply the search string, and Emacs visits the file containing the matching function name in the current window and goes to the first line of the function's definition. A variation of M-. is C-x 4 . (for find-tag-other-window), which uses another window instead of replacing the text in your current window.
M-的一个很好的功能。是它拾取光标所在的单词并将其用作默认搜索字符串。例如,如果您的光标位于字符串 my_function、M-上的任意位置。使用my_function作为默认值。因此,当您查看调用函数的 C 语句时,可以键入 M-。查看该函数的代码。
A nice feature of M-. is that it picks up the word the cursor is on and uses it as the default search string. For example, if your cursor is anywhere on the string my_function, M-. uses my_function as the default. Thus, when you are looking at a C statement that calls a function, you can type M-. to see the code for that function.
如果您有多个同名函数,则M-。查找文件中名称按字母顺序排在前面的函数。要查找其他的,您可以使用命令M-(对于tags-loop-continue)来查找下一个(如果没有更多的则抱怨)。如果您的目录包含多个程序,即,如果有多个名为main 的函数,则此功能特别有用。M-,还有其他用途,我们将看到。
If you have multiple functions with the same name, M-. finds the function in the file whose name comes first in alphabetical order. To find the others, you can use the command M-, (for tags-loop-continue) to find the next one (or complain if there are no more). This feature is especially useful if your directory contains more than one program, that is, if there is more than one function called main. M-, also has other uses, as we will see.
您可以使用标签表来搜索不仅仅是函数定义。命令Mx Tags-search Enter提示输入正则表达式;它会在标记表中列出的所有文件(例如所有 .c和.h文件)中搜索任何出现的正则表达式,无论它是否是函数名。此功能类似于本章前面讨论的grep工具。调用Tags-search后,您可以通过键入M- , 来查找其他匹配项。
You can use the tag table to search for more than just function definitions. The command M-x tags-search Enter prompts for a regular expression; it searches through all files listed in the tag table (such as, all .c and .h files) for any occurrence of the regular expression, whether it is a function name or not. This capability is similar to the grep facility discussed earlier in this chapter. After you have invoked tags-search, you can find additional matches by typing M-,.
还有类似的查询替换功能。命令 Mx Tags-query-replace Enter对标记表中列出的所有文件执行正则表达式查询替换(请参阅第 3 章)。与常规的query-replace-regexp命令一样,如果您在 tag-query-replace前面添加前缀参数(即Cu Mx Tags-query-replace Enter),Emacs 将仅替换整个单词的匹配项。例如,如果您想要替换printf的出现而不干扰fprintf的出现,则此功能非常有用。如果 使用Esc或Cg退出标签查询替换,稍后可以通过键入 M- , 来恢复它。
There is also an analogous query-replace capability. The command M-x tags-query-replace Enter does a regular expression query-replace (see Chapter 3) on all files listed in the tag table. As with the regular query-replace-regexp command, if you precede tags-query-replace with a prefix argument (i.e., C-u M-x tags-query-replace Enter), Emacs replaces only matches that are whole words. This feature is useful, for example, if you want to replace occurrences of printf without disturbing occurrences of fprintf. If you exit a tags-query-replace with Esc or C-g, you can resume it later by typing M-,.
命令Mx Tags-apropos完善了etags的搜索功能。如果给它一个正则表达式参数,它会打开一个
*Tags List*缓冲区,其中包含标签表中与正则表达式匹配的所有标签的列表(包括文件名和函数名)。例如,如果您想找出多文件 C 程序中的输出例程的名称,您可以使用参数print或write调用tags-apropos。
The command M-x tags-apropos rounds
out the search facilities of etags.
If you give it a regular expression argument, it opens a
*Tags List* buffer that contains a list of all
tags in the tag table (including names of files as well as functions)
that match the regular expression. For example, if you want to find
out the names of output routines in a multiple-file C program, you
could invoke tags-apropos with the
argument print or write.
最后,您可以键入Mx list-tags Enter列出表中的所有标记,即给定 C 文件的所有函数。在提示符处提供文件名,您将获得一个*Tags List*缓冲区,其中显示该文件中定义的函数名称及其返回类型(如果有)。请注意,如果将光标移至此列表,则可以使用M-。查看该函数的实际代码。米-。选择光标所在的单词作为默认函数名称,因此您只需将光标移动到要查看的函数名称并按M-即可。然后按Enter 键即可看到。
Finally, you can type M-x list-tags
Enter to list all the tags in the table—that is, all
the functions—for a given C file. Supply the filename at the
prompt, and you get a *Tags List* buffer showing
the names of functions defined in that file along with their return
types (if any). Note that if you move your cursor to this list, you
can use M-. to look at the actual
code for the function. M-. picks up
the word the cursor is on as the default function name, so you can
just move the cursor to the name of the function you want to see and
press M-. followed by Enter to see it.
还有最后一个共同特征 提一下。使用字体来帮助呈现代码非常流行——事实上,它现在已经很普遍了。与各种语言模式支持的缩进和格式不同,代码本身没有任何变化。但是当您处于字体锁定模式时,您的程序 看起来肯定会有所不同。
There's one last common feature to mention. The use of fonts to help present code is very popular—so popular, in fact, that it is now universal. Unlike the indentation and formatting supported by the various language modes, nothing in the code itself changes. But when you're in font-lock mode, your program certainly looks different.
您可以使用Mx font-lock-mode为任何语言模式打开此功能,亲自查看。关键词有特定的颜色;评论有不同的颜色并且通常是斜体的;字符串和文字有另一种颜色。它可以帮助快速浏览代码。许多人开始依赖它,就像依赖正确的缩进一样。如果您成为这些人中的一员,您会希望将其设置为所有语言会话的默认设置。您可以将以下行添加到 .emacs文件中来实现此目的:
You can turn on this feature for any language mode with M-x font-lock-mode to see for yourself. Keywords get a particular color; comments get a different color and are often italicized; strings and literals get yet another color. It can aid quick browsing of code. Many people come to depend on it much the way they rely on proper indentation. If you become one of those people, you'll want to make it the default for all language sessions. You can add the following line to your .emacs file to achieve this aim:
;;全局启用字体锁定 (全局字体锁定模式 t)
;; Turn on font-locking globally (global-font-lock-mode t)
如果您不喜欢默认值,则可以自定义使用的颜色和样式。Mx list-faces-display生成 Emacs 所知道的命名面孔的列表。您将看到类似于图 9-1所示屏幕的内容。
The colors and styles used are customizable if you don't like the defaults. M-x list-faces-display produces a list of the named faces Emacs knows about. You'll see something similar to the screen shown in Figure 9-1.
当然,在现实生活中,颜色和大胆之类的东西应该更加明显。您还会看到更多的面孔。您可以使用Mxmodify-face(一种简单的提示“向导”方法)或Mxcustomize-face(一种精美的交互式方法)来修改任何这些面孔。您还可以将行添加到.emacs 文件中以进行您喜欢的自定义。这是一个例子:
Of course, in real life, the colors and bold and whatnot should be more pronounced. You'll also see quite a few more faces. You can modify any of those faces with either M-x modify-face (a simple prompted "wizard" approach) or M-x customize-face (the big fancy interactive approach). You can also add lines to your .emacs file for your favorite customizations. Here's an example:
'(字体锁定注释面
((((类别颜色)(背景光))
(:前景“Firebrick”:倾斜斜体))))) '(font-lock-comment-face
((((class color) (background light))
(:foreground "Firebrick" :slant italic)))))请注意,并非所有显示器都支持粗体、斜体、下划线、颜色等所有可能的变体。这是“你的里程可能会有所不同”的典型案例。尽管如此,由于能够自行定制所有内容,您应该能够找到适合您的系统的组合。
Note that not all displays support all of the possible variations of bold, italic, underline, colors, and so on. This is a classic case of "your mileage may vary." Still, with the ability to customize it all yourself, you should be able to find a combination that works well on your system.
本章的其余部分将讨论几种特定于语言的模式,包括 JDEE,这是一套专门用于 Emacs 中 Java 开发领域的包。
The remaining sections in this chapter deal with several of the language-specific modes including JDEE, a suite of packages devoted to the world of Java development in Emacs.
如果您只对其中一两种语言感兴趣,则无需阅读所有这些部分。如果您使用 Emacs 有模式的另一种语言进行编程,您可能需要阅读以下部分之一来了解某种语言模式的“风味”;所有语言模式都具有相同的基本概念,因此这应该可以让您有一个良好的开端。事实上,许多语言模式都使用另一种模式作为基础。例如,Java模式实际上只是C模式的扩展。
You need not read all of these sections if you are interested in only one or two of the languages. If you program in another language for which Emacs has a mode, you may want to read one of the following sections to get the "flavor" of a language mode; all language modes have the same basic concepts, so this should get you off to a good start. Indeed, many language modes use another mode as a base. For example, Java mode is really just an extension of C mode.
[ 4 ]实际上,Emacs 向后搜索匹配的左括号的距离(以字符为单位)是有限制的:这是变量眨眼匹配帕伦距离的值,默认为 25,600。 “flash”的持续时间也是可配置的:它是blink-matching-delay的值(以秒为单位),默认值为1。
[4] Actually, there is a limit to how far back (in characters) Emacs searches for a matching open parenthesis: this is the value of the variable blink-matching-paren-distance, which defaults to 25,600. The duration of the "flash" is also configurable: it's the value (in seconds) of blink-matching-delay, whose default value is 1.
Emacs自动进入C模式 当您访问后缀为.c、.h、 .y(对于yacc 语法)或.lex(lex规范文件)的文件时。当您访问后缀为.C、 .H、.cc、 .hh、.cpp、 .cxx、.hxx、 .c++或.h++的文件时,Emacs 会调用 C++ 模式。您还可以通过键入Mx c-mode Enter手动将任何文件置于 C 模式。同样,您可以使用c++-mode将缓冲区置于 C++ 模式。
Emacs automatically enters C mode when you visit a file whose suffix is .c, .h, .y (for yacc grammars), or .lex (lex specification files). Emacs invokes C++ mode when you visit a file whose suffix is .C, .H, .cc, .hh, .cpp, .cxx, .hxx, .c++, or .h++. You can also put any file in C mode manually by typing M-x c-mode Enter. Similarly, you can use c++-mode to put a buffer into C++ mode.
C 和 C++ 模式都在同一个 Emacs Lisp 包中实现,称为cc-mode,[ 7 ],其中还包括 Mac OS X 中使用的 Objective-C 语言的模式。C 模式可以理解 ANSI C 和较旧的 Kernighan 和Ritchie C 语法。我们描述了 C 模式函数,但您应该假设所有内容也适用于 C++ 模式。 C++ 模式有少量附加功能,我们将在本节末尾进行描述。
Both C and C++ modes are implemented in the same Emacs Lisp package, called cc-mode,[7] which also includes a mode for the Objective-C language used in Mac OS X. C mode understands both ANSI C and the older Kernighan and Ritchie C syntax. We describe C mode functions, but you should assume that everything also applies to C++ mode. C++ mode has a small number of additional features, which we describe at the end of this section.
我们还应该注意到 Perl 的 Emacs 模式源自旧版本的 C 模式。如果您使用 Perl 进行编程,您会发现实际上 C 模式中的所有移动、缩进和格式化命令都同样适用于 Perl 模式,只是用perl-替换了它们名称中的c- 。 Emacs 对后缀为.pl 的文件调用 Perl 模式。 (不过,说实话,我们更喜欢 CPerl 模式,这将在本章后面讨论。)
We should also note that the Emacs mode for Perl is derived from an older version of C mode. If you program in Perl, you will find that virtually all of the motion, indentation, and formatting commands in C mode apply equally to Perl mode, with perl- replacing c- in their names. Emacs invokes Perl mode on files with suffix .pl. (However, to be honest we prefer CPerl mode, discussed later in this chapter.)
在 C 模式下,Emacs 理解本章前面描述的语法元素。分号 (;)、冒号 (:)、逗号 (,)、大括号({ 和 })和井号(#,用于 C 预处理器命令)都是电字符,这意味着当您键入时,Emacs 会自动缩进当前行他们。当您打开字体锁定模式时,它还会主动使用字体选项。
In C mode, Emacs understands the syntax elements described earlier in this chapter. The characters semicolon (;), colon (:), comma (,) curly braces ({ and }), and pound sign (#, for C preprocessor commands) are all electric, meaning that Emacs automatically indents the current line when you type them. It also actively uses the font options when you have font-lock mode turned on.
除了标准之外 用于单词和句子的 Emacs 命令(主要仅在多行注释中有用),C 模式包含了解语句、函数、[ 8 ]和预处理器条件的高级命令。表 9-3中显示了这些命令的摘要 。
In addition to the standard Emacs commands for words and sentences (which are mainly useful only inside multiline comments), C mode contains advanced commands that know about statements, functions,[8] and preprocessor conditionals. A summary of these commands appears in Table 9-3.
表 9-3。高级 C 运动命令
Table 9-3. Advanced C motion commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
嘛 M-a |
c-语句开头 c-beginning-of-statement |
移至当前语句的开头。 Move to the beginning of the current statement. |
|
我 M-e |
c-语句结束 c-end-of-statement |
移至当前语句的末尾。 Move to the end of the current statement. |
|
米q M-q |
c-填充段落 c-fill-paragraph |
如果在评论中,请填写该段落,保留缩进和修饰。 If in comment, fill the paragraph, preserving indentations and decorations. |
|
CM C-M-a |
开始的乐趣 beginning-of-defun |
移至该点周围函数体的开头。 Move to the beginning of the body of the function surrounding the point. |
|
CM C-M-e |
结束乐趣 end-of-defun |
移至函数末尾。 Move to the end of the function. |
|
CMh C-M-h |
c 标记功能 c-mark-function |
将光标置于函数的开头,将标记置于函数的结尾。 Put the cursor at the beginning of the function, the mark at the end. |
|
抄送Cq C-c C-q |
c-缩进-defun c-indent-defun |
根据缩进样式缩进整个函数。 Indent the entire function according to indentation style. |
|
铜铜 C-c C-u |
c-up-条件式 c-up-conditional |
移至当前预处理器条件的开头。 Move to the beginning of the current preprocessor conditional. |
|
抄送 Cp C-c C-p |
c-后向条件 c-backward-conditional |
移至上一个预处理器条件。 Move to the previous preprocessor conditional. |
|
抄送中国 C-c C-n |
c-前向条件 c-forward-conditional |
移至下一个预处理器条件。 Move to the next preprocessor conditional. |
请注意,语句运动命令分别具有与back-sentence和forward-sentence相同的键绑定。事实上,如果您在 C 注释中使用它们,它们将充当句子命令。
Notice that the statement motion commands have the same key bindings as backward-sentence and forward-sentence, respectively. In fact, they act as sentence commands if you use them within a C comment.
类似地,Mq通常是 填充段落命令; C 模式增强了它在行首保留缩进和装饰字符的能力。例如,如果您的光标位于此评论中的任意位置:
Similarly, M-q is normally the fill-paragraph command; C mode augments it with the ability to preserve indentations and decorative characters at the beginnings of lines. For example, if your cursor is anywhere in this comment:
/* 这是 * A * 注释段落的权利差异很大 * 边距。 * 持续一段时间, * 然后停止。 */
/* This is * a * comment paragraph with wildly differing right * margins. * It goes on for a while, * then stops. */
输入Mq会得到以下结果:
typing M-q has this result:
/* 这是一个右边界差异很大的注释段落。 * 它持续了一段时间,然后停止。 */
/* This is a comment paragraph with wildly differing right margins. * It goes on for a while, then stops. */
如果您必须费力地阅读别人的大量代码,您会发现预处理器条件运动命令是天赐之物。特别是如果您面对的是为在各种系统上运行而构建的代码(例如 Emacs 本身),通常您需要回答的最重要的问题是“实际编译了哪些代码?”
You will find that the preprocessor conditional motion commands are a godsend if you have to slog through someone else's voluminous code. Especially if you're faced with code built to run on a variety of systems—like Emacs itself—often the most important question you need answered is, "What code is actually compiled?"
使用Cc Cu,您可以立即知道哪个预处理器条件控制相关代码。考虑这个代码块:
With C-c C-u, you can tell instantly what preprocessor conditional governs the code in question. Consider this code block:
#定义LUCYX
#define BADEXIT -1
#ifdef 露西克斯
...
*ptyv = open("/dev/ptc", O_RDWR | O_NDELAY, 0);
如果(fd<0)
返回BADEXIT;
...
#别的
...
fprintf (stderr, "你不能在这个系统上这样做!");
...
#万一#define LUCYX
#define BADEXIT -1
#ifdef LUCYX
...
*ptyv = open ("/dev/ptc", O_RDWR | O_NDELAY, 0);
if (fd < 0)
return BADEXIT;
...
#else
...
fprintf (stderr, "You can't do that on this system!");
...
#endif想象一下,省略号 (...) 代表数百行代码。现在假设您尝试确定在什么条件下打开文件/dev/ptc 。如果您的光标位于该行代码上,您可以键入Cc Cu,然后光标会移动到#ifdef LUCYX行- 告诉您如果您使用的是 LUCYX 系统,则代码已编译。如果您想跳过不会编译的代码并直接转到条件的末尾,请输入Cc Cn。我们将在本节后面看到另一个对于处理 C 预处理器代码有用的命令。
Imagine that the ellipses ( . . . ) represent hundreds of lines of code. Now suppose you are trying to determine under what conditions the file /dev/ptc is opened. If your cursor is on that line of code, you can type C-c C-u, and the cursor moves to the line #ifdef LUCYX—telling you that the code is compiled if you're on a LUCYX system. If you want to skip the code that would not be compiled and go directly to the end of the conditional, type C-c C-n. We will see another command that is useful for dealing with C preprocessor code later in this section.
C 语句和语句块定界符字符绑定到命令,除了插入适当的字符之外,还提供适当的缩进。这些字符是{ , } , ;、 和 :(用于标签和开关盒)。例如,如果您要关闭语句块或函数体,您可以按Cj(或Enter)并输入},Emacs 会将其与其匹配的 {对齐。这样您就无需向后滚动代码来找出{所在的列。
C statement and statement block delimiter characters are bound to commands that, in addition to inserting the appropriate character, also provide proper indentation. These characters are {, }, ;, and : (for labels and switch cases). For example, if you are closing out a statement block or function body, you can press C-j (or Enter) and type }, and Emacs lines it up with its matching {. This eliminates the need for you to scroll back through the code to find out what column the { is in.
由于}是括号类型字符,因此当您键入}时,Emacs 会尝试“闪现”匹配的{。如果匹配的{位于窗口中显示的文本之外,则 Emacs 会在迷你缓冲区中打印包含{的行。此外,如果该行的{后面只有空格(空格或制表符),Emacs 还会打印一个^J(表示Cj),后面跟着下一行,从而更好地了解{的上下文。
Because } is a parenthesis-type character, Emacs attempts to "flash" a matching { when you type }. If the matching { is outside of the text displayed in your window, Emacs instead prints the line containing the { in the minibuffer. Furthermore, if only whitespace (blanks or tabs) follows the { on its line, Emacs also prints a ^J (for C-j) followed by the next line, thus giving a better idea of the context of the {.
回想一下本章前面的“times”例子。假设您正在输入 }来结束函数,而 开始函数体的{位于屏幕外。开头{后面的行没有代码 ,因此在键入}后您会在迷你缓冲区中看到以下内容:
Recall the "times" example earlier in this chapter. Let's say you are typing in a } to end the function, and the { that begins the function body is off-screen. There is no code on the line following the beginning {, so you see the following in the minibuffer after you type }:
匹配 {^J int i;Matches {^J int i;C 语言或任何编程风格 就此而言,语言是一件非常个人的事情。 C 程序员从各种书籍中学习或通过参考其他人的各种不同代码片段来学习;最终,他们形成了一种个人风格,这种风格可能符合也可能不符合他们所学到的风格。
Coding style in C—or any programming language for that matter—is a very personal thing. C programmers learn from various books or by referring to various different pieces of other people's code; eventually they evolve a personal style that may or may not conform to those that they learned from.
C 模式提供了一组丰富的功能来自定义其缩进行为,这反映了这种学习语言的方式。在最简单的层面上,您可以按名称选择编码样式。然后,如果您不满意,您可以自定义您选择的样式,甚至从头开始创建自己的样式。然而,后面的任务需要相当多的 Emacs Lisp 编程知识(参见第 11 章),也许还需要一点勇气。
C mode provides a rich set of features for customizing its indentation behavior that mirrors this way of learning the language. At the simplest level, you can choose a coding style by name. Then, if you're not satisfied, you can customize your chosen style or even create your own from scratch. The latter tasks, however, require a fair amount of Emacs Lisp programming knowledge (see Chapter 11) and perhaps a bit of bravery.
您可以使用命令Mx c-set-style选择命名编码样式。此命令会提示您输入所需样式的名称。此时最简单的事情是输入Tab,即完成字符(请参阅第 14 章),这将打开一个
*Completions*列出所有选项的窗口。输入其中之一并按Enter 键选择它。
You can choose a named coding style with the command M-x c-set-style. This command prompts you for
the name of the style you want. The easiest thing to do at this point
is to type Tab, the completion
character (see Chapter 14), which brings up a
*Completions* window that lists all of the
choices. Type one of them and press Enter to select it.
默认情况下,Emacs 加载了表 9-4中所示的样式。
By default, Emacs comes loaded with the styles shown in Table 9-4.
表 9-4。内置 cc 模式缩进样式
Table 9-4. Built-in cc-mode indentation styles
|
风格 Style |
描述 Description |
|---|---|
|
BSD bsd |
BSD 派生版本的 Unix 代码中使用的样式。 Style used in code for BSD-derived versions of Unix. |
|
CC模式 cc-mode |
默认编码风格,所有其他编码风格均源自该风格。 The default coding style, from which all others are derived . |
|
埃勒姆特尔 ellemtel |
瑞典 Ellemtel 电信系统实验室的 C++ 文档中使用的样式。 Style used in C++ documentation from Ellemtel Telecommunication Systems Laboratories in Sweden . |
|
格努 gnu |
Emacs 本身和其他 GNU 相关程序的 C 代码中使用的样式。 Style used in C code for Emacs itself and other GNU-related programs . |
|
爪哇 java |
Java 代码中使用的样式(Java 模式的默认样式)。 Style used in Java code (the default for Java mode). |
|
克&r k&r |
关于 C 的经典文本风格,Kernighan 和 Ritchie 的《C 编程语言》。 Style of the classic text on C, Kernighan and Ritchie's The C Programming Language . |
|
操作系统 linux |
作为 Linux 内核一部分的 C 代码中使用的样式。 Style used in C code that is part of the Linux kernel. |
|
Python python |
python 扩展中使用的样式。 Style used in python extensions. |
|
斯特鲁斯特鲁普 stroustrup |
C++ 编码风格的标准参考著作,Bjarne Stroustrup 的《C++ 编程语言》。 C++ coding style of the standard reference work, Bjarne Stroustrup's The C++ Programming Language . |
|
用户 user |
您对.emacs或通过 Custom 进行的自定义(请参阅第 10 章)。如果您设置了这些自定义,所有其他样式都会继承它们。 Customizations you make to .emacs or via Custom (see Chapter 10). All other styles inherit these customizations if you set them. |
|
怀特史密斯 whitesmith |
Whitesmith Ltd. 的 C 和 C++ 编译器文档中使用的样式。 Style used in Whitesmith Ltd.'s documentation for their C and C++ compilers . |
为了展示其中一些样式的工作原理,让我们从本章前面的 C 函数示例开始:
To show how some of these styles work, let's start with the C function example from earlier in this chapter:
整数倍 (x, y)
整数x,y;
{
整数我;
整数结果 = 0;
对于 (i = 0; i < x; i++)
{
结果+=y;
}
}int times (x, y)
int x, y;
{
int i;
int result = 0;
for (i = 0; i < x; i++)
{
result += y;
}
}如果您在此代码周围定义一个区域并键入CM-\(表示indent-region),Emacs 将按照默认样式重新格式化代码,如下所示:
If you define a region around this code and you type C-M-\ (for indent-region), Emacs reformats the code in the default style like this:
整数倍 (x, y)
整数x,y;
{
整数我;
整数结果 = 0;
对于 (i = 0; i < x; i++)
{
结果+=y;
}
}int times (x, y)
int x, y;
{
int i;
int result = 0;
for (i = 0; i < x; i++)
{
result += y;
}
}如果您输入抄送。 (对于c-set-style),输入k&r,然后重复重新格式化,代码如下所示:
If you type C-c . (for c-set-style), enter k&r, and then repeat the reformatting, the code looks like this:
整数倍 (x, y)
整数x,y;
{
整数我;
整数结果 = 0;
对于 (i = 0; i < x; i++)
{
结果+= y;
}
}int times (x, y)
int x, y;
{
int i;
int result = 0;
for (i = 0; i < x; i++)
{
result += y;
}
}或者,如果您想切换到 GNU 样式缩进,请选择 gnu样式并重新格式化。结果是:
Or, if you want to switch to GNU-style indentation, choose the style gnu and reformat. The result is:
整数倍 (x, y)
整数x,y;
{
整数我;
整数结果 = 0;
对于 (i = 0; i < x; i++)
{
结果+= y;
}
}int times (x, y)
int x, y;
{
int i;
int result = 0;
for (i = 0; i < x; i++)
{
result += y;
}
}一旦决定了编码风格,您可以通过在.emacs文件中添加一行来永久设置它,如下所示:
Once you decide on a coding style, you can set it up permanently by putting a line in your .emacs file that looks like this:
(添加钩子'c-模式钩子
'( 拉姆达 ( )
(c-set-style“ stylename”)))(add-hook 'c-mode-hook
'(lambda ( )
(c-set-style "stylename")))不幸的是,我们必须等到第 11 章才能准确理解这段代码的作用。现在,请确保(lambda在第二行中的之前插入单引号 (')
。
Unfortunately, we'll have to wait until Chapter 11 to understand exactly what this code does.
For now, make sure that you insert a single quote (') before the
(lambda in the second line.
每种编码风格都包含微妙之处,使得 Emacs 实现起来并不简单。旧版本的 Emacs 通过定义几个控制不同缩进级别的变量来实现这一点。这些并不容易使用,而且坦率地说,并没有真正涵盖每种风格 100% 的细微差别。相比之下,当前版本的 C 模式使用了相当大的变量集 — 事实上,除了顽强的 Emacs Lisp 黑客之外,任何人都无法处理。
Each coding style contains subtleties that makes it nontrivial for Emacs to implement. Older versions of Emacs did this by defining several variables that controlled various indentation levels; these were not easy to work with and, frankly, did not really cover 100 percent of the nuances of each style. The current version of C mode, in contrast, uses a considerably larger set of variables—too large, in fact, for anyone other than hardy Emacs Lisp hackers to deal with.
因此,C 模式会在命名样式下跟踪这些变量组及其值。一个名为c-style-alist的巨大变量包含所有样式及其相关信息。您可以通过更改现有样式中的变量值或添加您自己的样式来自定义此野兽。有关更多详细信息,请查看系统 Emacs Lisp 目录中的cc-mode.el文件 (请参阅第 11 章)。
Therefore, C mode keeps track of groups of these variables and their values under named styles. One huge variable, called c-style-alist, contains all of the styles and their associated information. You can customize this beast either by changing values of variables within existing styles or by adding a style of your own. For further details, look in the file cc-mode.el in your system's Emacs Lisp directory (see Chapter 11).
C 模式包含许多其他有用的功能,从普遍有用到神秘莫测。也许其中最有趣的是添加额外电动功能的两种方法 某些击键,称为自动换行和 饥饿删除键。[ 9 ]
C mode contains a number of other useful features, ranging from the generally useful to the arcanely obscure. Perhaps the most interesting of these are two ways of adding additional electric functionality to certain keystrokes, called auto-newline and hungry-delete-key.[9]
启用自动换行后,每当您键入分号 (;)、大括号({ 或 }),或者在某些时候键入逗号 (,) 或冒号时,它都会导致 Emacs 添加换行符并正确缩进新行(:)。这些功能可以节省您一些时间,并帮助您以一致的风格格式化代码。
When auto-newline is enabled, it causes Emacs to add a newline character and indent the new line properly whenever you type a semicolon (;), curly brace ({ or }), or, at certain times, comma (,) or colon (:). These features can save you some time and help you format your code in a consistent style.
默认情况下自动换行处于关闭状态。要打开它,请键入Cc Ca for c-toggle-auto-state。 (重复相同的命令可再次将其关闭。)您将看到模式行中的(C)更改为(C/a)作为指示。作为其工作原理的示例,请尝试输入我们的函数的代码times( )
。输入前两行,直到第二行的y :
Auto-newline is off by default. To turn it on, type C-c C-a for c-toggle-auto-state. (Repeat the same command
to turn it off again.) You will see the (C) in the mode line change to (C/a) as an indication. As an example of how
it works, try typing in the code for our times( )
function. Type the first two lines up to the y on the second line:
整数倍 (x, y) 整数 x, y
int times (x, y) int x, y
现在按分号;请注意,Emacs 会插入换行符并将您带到下一行:
Now press the semicolon; notice that Emacs inserts a newline and brings you down to the next line:
整数倍 (x, y) 整数x,y;
int times (x, y) int x, y;
输入左大括号,然后又发生了:
Type the opening curly brace, and it happens again:
整数倍 (x, y)
整数x,y;
{int times (x, y)
int x, y;
{当然,输入 { 后 Emacs 缩进的空格数取决于您使用的缩进样式。
Of course, the number of spaces Emacs indents after you type the { depends on the indentation style you are using.
另一个可选的电动功能,饥饿删除键,默认情况下也是关闭的。要打开它,请输入Cc Cd(对于 c-toggle-hungry-state)。您将看到模式行上的 (C)更改为(C/h),或者如果您打开了自动换行符,则从(C/a)更改为(C/ah)。
The other optional electric feature, hungry-delete-key, is also off by default. To toggle it on, type C-c C-d (for c-toggle-hungry-state). You will see the (C) on the mode line change to (C/h), or if you have auto-newline turned on, from (C/a) to (C/ah).
打开饥饿删除键 使Del键能够删除该点左侧的所有空格。要返回到前面的示例,假设您刚刚键入了左花括号。然后,如果您按Del,Emacs 会将所有内容删除回大括号:
Turning on hungry-delete-key empowers the Del key to delete all whitespace to the left of the point. To go back to the previous example, assume you just typed the open curly brace. Then, if you press Del, Emacs deletes everything back to the curly brace:
整数倍 (x, y)
整数x,y;
{int times (x, y)
int x, y;
{您可以使用命令Cc Ct(对于c-toggle-auto-hungry-state)切换auto-newline和eager-delete-key的状态。
You can toggle the states of both auto-newline and hungry-delete-key with the command C-c C-t (for c-toggle-auto-hungry-state).
如果您希望在调用 Emacs 时默认启用这些功能之一,则可以在.emacs文件中添加如下行 :
If you want either of these features on by default when you invoke Emacs, you can put lines like the following in your .emacs file:
(添加钩子'c-模式钩子
'( 拉姆达 ( )
(c-切换-自动状态)))(add-hook 'c-mode-hook
'(lambda ( )
(c-toggle-auto-state)))如果您想将此自定义与另一个 C 模式自定义结合起来,例如前面示例中的缩进样式,则需要将 Emacs Lisp 代码行组合如下:
If you want to combine this customization with another C mode customization, such as the indentation style in the previous example, you need to combine the lines of Emacs Lisp code as follows:
(添加钩子'c-模式钩子
'( 拉姆达 ( )
(c-set-style“ stylename”)
(c-切换-自动状态)))(add-hook 'c-mode-hook
'(lambda ( )
(c-set-style "stylename")
(c-toggle-auto-state)))同样,我们将在第 11 章的“定制现有模式”中了解这个钩子结构的含义 。
Again, we will see what this hook construct means in "Customizing Existing Modes" in Chapter 11.
C模式还提供了对注释的支持;在本章前面,我们看到了这种支持的示例。然而,还有另一个特点。您可以自定义Mj(用于indent-new-comment-line),以便 Emacs 在下一行继续相同的注释,而不是创建一对新的分隔符。变量comment-multi-line控制此功能:如果将其设置为nil(默认值),Emacs 将在下一行生成新注释,如本章前面的示例所示:
C mode also provides support for comments; earlier in the chapter, we saw examples of this support. There is, however, another feature. You can customize M-j (for indent-new-comment-line) so that Emacs continues the same comment on the next line instead of creating a new pair of delimiters. The variable comment-multi-line controls this feature: if it is set to nil (the default), Emacs generates a new comment on the next line, as in the example from earlier in the chapter:
结果+= y; /* 被乘数相加 */
/* * /result += y; /* add the multiplicand */
/* */此结果是在被乘数后键入Mj的结果,它表明光标已定位到可以键入第二个注释行的文本。但是,如果将comment-multi-line设置为t (或nil以外的任何值),则会得到以下结果:
This outcome is the result of typing M-j after multiplicand, and it shows that the cursor is positioned so that you can type the text of the second comment line. However, if you set comment-multi-line to t (or any value other than nil), you get this outcome instead:
结果+= y; /* 被乘数相加
* /result += y; /* add the multiplicand
*/我们将介绍的最后一个功能是Cc Ce(用于c-macro-expand)。与条件编译运动命令(例如,Cc Cu表示c-up-conditional)一样,c-macro-expand可以帮助您回答经常遇到的难题:“实际上编译了哪些代码?”当您的源代码包含大量预处理器指令时。
The final feature we'll cover is C-c C-e, (for c-macro-expand). Like the conditional compilation motion commands (e.g., C-c C-u for c-up-conditional), c-macro-expand helps you answer the often difficult question, "What code actually gets compiled?" when your source code contains a morass of preprocessor directives.
要使用c-macro-expand,您必须首先定义一个区域。然后,当您键入Cc Ce时,它会获取该区域内的代码,将其传递给实际的 C 预处理器,并将输出放置在名为 的窗口中*Macroexpansion*。
To use c-macro-expand, you must
first define a region. Then, when you type C-c
C-e, it takes the code within the region, passes it
through the actual C preprocessor, and places the output in a window
called *Macroexpansion*.
要了解此过程的工作原理,让我们回到本章前面包含 C 预处理器指令的代码示例:
To see how this procedure works, let's go back to the code example from earlier in this chapter that contains C preprocessor directives:
#定义LUCYX
#define BADEXIT -1
#ifdef 露西克斯
*ptyv = open("/dev/ptc", O_RDWR | O_NDELAY, 0);
如果(fd<0)
返回BADEXIT;
#别的
fprintf (stderr, "你不能在这个系统上这样做!");
#万一#define LUCYX
#define BADEXIT -1
#ifdef LUCYX
*ptyv = open ("/dev/ptc", O_RDWR | O_NDELAY, 0);
if (fd < 0)
return BADEXIT;
#else
fprintf (stderr, "You can't do that on this system!");
#endif如果您在该代码块周围定义一个区域并输入Cc Ce,您会看到以下消息:
If you define a region around this chunk of code and type C-c C-e, you see following the message:
在区域上调用 /lib/cpp -C...
Invoking /lib/cpp -C on region...
接下来是:
followed by this:
完毕
done
然后您会看到一个*Macroexpansion*包含以下结果的窗口:
Then you see a *Macroexpansion* window that
contains this result:
*ptyv = open("/dev/ptc", O_RDWR | O_NDELAY, 0);
如果(fd<0)
返回-1; *ptyv = open ("/dev/ptc", O_RDWR | O_NDELAY, 0);
if (fd < 0)
return -1;如果您想将c-macro-expand 与不同的 C 预处理器命令一起使用,而不是默认的 /lib/cpp -C(-C选项表示“在输出中保留注释”),您可以设置变量 c-macro -预处理器。例如,如果您想使用文件名为 /usr/local/lib/cpp的实验性预处理器,请将以下行放入您的.emacs文件中:
If you want to use c-macro-expand with a different C preprocessor command, instead of the default /lib/cpp -C (the -C option means "preserve comments in the output"), you can set the variable c-macro-preprocessor. For example, if you want to use an experimental preprocessor whose filename is /usr/local/lib/cpp, put the following line in your .emacs file:
(setq c-宏预处理器“/usr/local/lib/cpp -C”)
(setq c-macro-preprocessor "/usr/local/lib/cpp -C")
强烈建议您保留-C选项,以免删除代码中的注释。
It's highly recommended that you keep the -C option for not deleting comments in your code.
正如我们之前提到的,C++ 模式使用与 C 模式相同的 Emacs Lisp 包。当您处于 C++ 模式时,Emacs 理解 C++ 语法,而不是 C(或 Objective-C)语法。这会导致此处讨论的某些命令的行为方式有所不同,但用户不会注意到。
As we mentioned before, C++ mode uses the same Emacs Lisp package as C mode. When you're in C++ mode, Emacs understands C++ syntax, as opposed to C (or Objective-C) syntax. That results in differences in how some of the commands discussed here behave, but in ways that are not noticeable to the user.
C++ 和 C 模式之间几乎没有明显的区别。最重要的是您需要放入 .emacs文件中以自定义 C++ 模式的 Emacs Lisp 代码:您使用c++- mode-hook代替 c-mode-hook。例如,如果您希望将 C++ 模式的缩进样式设置为带有自动换行符的 Stroustrup,而不是默认样式,请将以下内容放入您的 .emacs文件中:
There are few apparent differences between C++ and C mode. The most important is the Emacs Lisp code you need to put in your .emacs file to customize C++ mode: instead of c-mode-hook, you use c++-mode-hook. For example, if you want C++ mode's indentation style set to Stroustrup with automatic newlines instead of the default style, put the following in your .emacs file:
(添加钩子'c++-模式钩子
'( 拉姆达 ( )
(c-set-style“Stroustrup”)
(c-切换-自动状态)))(add-hook 'c++-mode-hook
'(lambda ( )
(c-set-style "Stroustrup")
(c-toggle-auto-state)))请注意,您可以通过这种方式分别为 C 模式和 C++ 模式设置挂钩,这样,如果您使用两种语言进行编程,则可以为每种语言设置单独的缩进样式。
Notice that you can set hooks for C mode and C++ mode separately this way, so that if you program in both languages, you can set up separate indentation styles for each.
C++ 模式提供了一个附加命令:Cc :(用于c-scope-operator)。此命令插入 C++ 双冒号 (::) 作用域运算符。这是必要的,因为冒号 (:) 通常与电气功能绑定,当您不希望这样做时,可以重新缩进该行。范围运算符几乎可以出现在 C++ 代码中的任何位置,而单个冒号通常表示case标签,需要特殊缩进。 Cc :命令可能看起来有些笨拙,但它是解决 C++ 语言中语法冲突的必要解决方法。
C++ mode provides an additional command: C-c : (for c-scope-operator). This command inserts the C++ double colon (::) scope operator. It's necessary because the colon (:) is normally bound to electric functionality that can reindent the line when you don't want that done. The scope operator can appear virtually anywhere in C++ code whereas the single colon usually denotes a case label, which requires special indentation. The C-c : command may seem somewhat clumsy, but it's a necessary workaround to a syntactic clash in the C++ language.
最后,C 和 C++ 模式都包含命令c-forward-into-nomenclature和c-backward-into-nomenclature,默认情况下这些命令不绑定到任何击键。它们分别类似于forward-word和backward-word,但它们将单词中间的大写字母视为开始新单词。例如,它们将ThisVariableName 视为三个单独的单词,而标准的前向单词和后向单词命令将其视为一个单词。 ThisTypeOfVariableName是 C++ 程序员使用的一种样式,与 this_type_of_variable_name不同,后者在老式 C 代码中更常见。
Finally, both C and C++ mode contain the commands c-forward-into-nomenclature and c-backward-into-nomenclature, which aren't bound to any keystrokes by default. These are like forward-word and backward-word, respectively, but they treat capital letters in the middle of words as if they were starting new words. For example, they treat ThisVariableName as if it were three separate words while the standard forward-word and backward-word commands treat it as one word. ThisTypeOfVariableName is a style used by C++ programmers, as opposed to this_type_of_variable_name, which is somehow more endemic to old-school C code.
C++ 程序员可能希望将c-forward-into-nomenclature和c-backward-into-nomenclature绑定到通常绑定到标准单词运动命令的击键。我们将在第 11 章的“自定义现有模式”中向您展示如何执行此操作。
C++ programmers may want to bind c-forward-into-nomenclature and c-backward-into-nomenclature to the keystrokes normally bound to the standard word motion commands. We show you how to do this in "Customizing Existing Modes" in Chapter 11.
我们已经介绍了 C 和 C++ 模式的主要功能,但实际上这些模式还包含更多功能,其中大多数功能相当晦涩,或者仅适用于精通 Emacs Lisp 的铁杆定制者。查看 Emacs Lisp 包cc-mode.el — 以及不断扩展的cc- helper 包列表 — 了解更多详细信息。
We've covered the main features of C and C++ modes, but actually these modes include many more features, most of them quite obscure or intended only for hardcore Emacs Lisp-adept customizers. Look in the Emacs Lisp package cc-mode.el—and the ever-expanding list of cc- helper packages—for more details.
[ 7 ]我们知道!没有Mx cc 模式。这可能会令人困惑。请记住,这些模式是直接以其支持的语言命名的。
[7] We know! There is no M-x cc-mode. It can be confusing. Just try to remember that the modes are named directly after the language they support.
正如我们之前提到的,最新版本的 Emacs 内置了对 Java 的支持(Java 模式基于 cc-mode)。我们将简要探讨 Java 模式,然后更深入地了解Emacs 的 Java 开发环境 (JDEE)。
As we mentioned earlier, recent versions of Emacs come with support for Java built-in (Java mode is based on cc-mode). We'll explore Java mode briefly and then take a more in-depth look at the Java Development Environment for Emacs (JDEE).
Java 模式共享所有 上面提到的格式和字体特性,但具体了解 Java 语言。打开任何.java文件时,您都会进入 Java 模式 。
Java mode shares all of the formatting and font features mentioned above, but understands the Java language specifically. You get thrown into Java mode when opening any .java file.
在 Java 模式下工作时,您可以使用与 C 模式下完全相同的功能。当字体锁定模式打开时,语法高亮处理 Java 关键字和语法。您可以使用Ma和Me导航 Java 命令 。当注释掉一个区域时,它使用 C++ 风格//注释。
When working in Java mode, you have exactly the same features available as you do in C mode. Syntax highlighting handles Java keywords and syntax when font-lock mode is turned on. You can navigate Java commands using M-a and M-e. When commenting out a region, it uses the C++ style // comments.
如果您选择将throws或extends子句分布在多行上,您会注意到缩进对齐命令有一个小的增强。例如,考虑以下方法声明:
You'll notice a small augmentation in the indent alignment commands if you choose to spread your throws or extends clauses over multiple lines. For example, consider the following method declaration:
公共对象 getNetResource(String 主机, int 端口, String resName)
抛出 IllegalArgumentException,
IO异常,
SQL异常,
文件未找到异常
{public Object getNetResource(String host, int port, String resName)
throws IllegalArgumentException,
IOException,
SQLException,
FileNotFoundException
{如果标记该区域并运行MC-\ 来缩进该区域,它将对例外列表使用特殊的对齐方式:
If you mark the region and run M-C-\ to indent the region, it uses a special alignment for the exception list:
公共对象 getNetResource(String 主机, int 端口, String resName)
抛出 IllegalArgumentException,
IO异常,
SQL异常,
文件未找到异常
{public Object getNetResource(String host, int port, String resName)
throws IllegalArgumentException,
IOException,
SQLException,
FileNotFoundException
{一切都按照预期进行——只是以 Java 作为操作的核心语言。然而,除了休闲 Java 编辑之外,您还应该阅读有关 JDEE 的下一节。
It all works like it is supposed to—just with Java as the language at the core of the action. However, for more than casual Java editing, you should read the next section on the JDEE.
虽然你当然可以立即开始使用内置 Java 模式,如果您不仅仅是偶尔进行 Java 编程,您可能想进入 Paul Kinnucan 的 Emacs Java 开发环境 (JDEE) 的世界。它将 Emacs 引入了 Java IDE 领域。您不会找到 GUI 构建器,但其他一切都已就位并准备就绪。
While you can certainly get started right away with the built-in Java mode, if you do more than occasional Java programming, you might want to venture into the world of Paul Kinnucan's Java Development Environment for Emacs (JDEE). It takes Emacs into the realm of Java IDE. You won't find a GUI builder, but everything else is in place and ready to roll.
您可以从http://jdee.sunsite.dk/在线获取最新版本的 JDEE 。[ 10 ]该站点对于 JDEE 的启动和运行至关重要。您会发现各种提示和技巧,以及所有附加功能的完整用户文档。
You can pick up the latest version of the JDEE online from http://jdee.sunsite.dk/.[10] This site is essential to getting the JDEE up and running. You'll find all sorts of tips and tricks and full user documentation on all of the bells and whistles is available.
在安装 JDEE 之前,您需要以下组件:
Before you can install the JDEE, you'll need the following components:
可在 SourceForge ( http://cedet.sourceforge.net/ ) 上获取或通过 JDEE 主页上的链接获取。该集合非常受欢迎,作为更有趣的程序员工具的基础。您可能已经安装了足够的版本,但最好获取最新版本。
Available on SourceForge (http://cedet.sourceforge.net/) or by following the links from the JDEE home page. This collection is quite popular as a foundation for more interesting programmer tools. You may already have a sufficient version installed, but it's best to get the latest release.
可从 JDEE 站点单独下载。
Available as a separate download from the JDEE site.
虽然从技术上讲,在 Emacs 中编辑文件不需要 JDK,但需要 JDK 才能利用 JDEE 的任何编译或调试功能。您还必须注册您计划使用的每个 JDK,稍后会详细介绍。
While technically not required for editing files in Emacs, a JDK is required to take advantage of any of the compilation or debugging features of the JDEE. You'll also have to register each JDK you plan to use, but more on that later.
安装 CEDET 是 如果您有可用的make命令,则相当简单。 (对于 Windows 用户,您需要安装 Cygnus Unix Distribution。它使您可以访问大量 Unix 工具,这些工具的用处远远超出了安装 JDEE 的范围。)
Installing CEDET is fairly straightforward if you have a make command available. (For Windows users, you'll want to have the Cygnus Unix Distribution installed. It gives you access to a large subset of Unix tools which will come in handy far beyond the installation of the JDEE.)
从 SourceForge 下载 CEDET 发行版后,将其解压到您想要存放的位置。打开终端窗口(或在 Windows 上启动 Cygwin bash 终端)并更改到解压发行版的目录。从那里您应该能够运行以下命令:
After you download the CEDET distribution from SourceForge, unpack it wherever you want it to reside. Open a terminal window (or start a Cygwin bash terminal on Windows) and change to the directory where you unpacked the distribution. From there you should be able to run the following command:
shell$使 EMACS=
/path/to/emacs
shell$ make EMACS=
/path/to/emacs
该过程可能需要几分钟才能完成。 Lisp 文件将为您编译。
That process will probably take a few minutes to complete. The Lisp files will be compiled for you.
当make命令完成时,您应该处于良好状态。 CEDET 的最后一步是更新您的 .emacs文件:
When the make command completes, you should be in good shape. The last step for CEDET is to update your .emacs file:
;;打开CEDET的有趣部分
(setq 语义加载打开有用的东西)
;;加载CEDET
(加载文件“/ cedet路径/common/cedet.el”);; Turn on CEDET's fun parts
(setq semantic-load-turn-useful-things-on t)
;; Load CEDET
(load-file "/path-to-cedet/common/cedet.el")安装ELisp库包 从 JDEE 站点获取也很简单。将下载的文件解压到您喜欢的任何位置,但在运行make命令之前,您需要编辑 Makefile 并配置表 9-5中概述的条目 以匹配您的系统。
Installing the ELisp library package from the JDEE site is also straightforward. Unpack the downloaded file wherever you like, but before you run the make command, you'll need to edit the Makefile and configure the entries outlined in Table 9-5 to match your system.
表 9-5。 JDEE Makefile 条目
Table 9-5. JDEE Makefile entries
运行带有 安装选项的make命令来完成所有设置:
Run the make command with the install option to get everything set up:
外壳$make installshell$ make installELisp 库的最后一步是确保 Emacs 默认值认可新包。您只需将新目录添加到加载路径 变量中,如下所述。
The last step for the ELisp library is to make sure the Emacs defaults acknowledge the new package. You simply need to add the new directory to your load-path variable, as described next.
ELisp 库实际上提供了一个与您安装包的位置相匹配的简单模板文件。make过程完成后,您运行make命令的目录中应该有一个 elib_startup.el文件。该文件包含您需要添加到 .emacs文件中的行,或者您可以将其与系统 default.el文件合并以供每个人使用。 ( default.el文件通常可以在你的site-lisp目录中找到 。第 11 章有更多细节。)
The ELisp library actually provides a simple template file that matches where you installed the package. After the make process completes, you should have an elib_startup.el file in the directory where you ran the make command. That file contains the line you'll need to add to your .emacs file or you can merge it with the system default.el file for everyone to use. (The default.el file is often found in your site-lisp directory. Chapter 11 has more details.)
Five basic steps are required to install the JDEE on your system:
下载并安装必要的先决条件。
Get the necessary prerequisites downloaded and installed.
更新加载路径 ( .emacs )。
Update the load path (.emacs).
将 JDEE 设置为在启动时加载 ( .emacs )。
Set theJDEE to load at startup (.emacs).
编译 JDEE .el文件(可选)。
Compile JDEE .el files (optional).
注册您的 JDK(可选)。
Register your JDKs (optional).
上一节介绍了第一步。在继续之前,请确保满足这些先决条件。接下来的步骤可以在您的.emacs文件中处理。 JDEE 站点建议将以下条目作为最小设置;我们在这里摘录它们(经过一两个小调整)以方便参考。
The previous section covered the first step. Make sure you take care of those prerequisites before continuing. The next steps can be handled in your .emacs file. The JDEE site proposes the following entries as a minimal setup; we excerpt them here (with one or two small tweaks) for easy reference.
;;此 .emacs 文件说明了最小设置
;;运行 JDEE 所需的。
;;设置调试选项以在发生错误时启用回溯
;;出现问题。
(setq 错误调试 t)
;;更新 Emacs 加载路径以包含以下路径
;; JDEE 及其需要的包。这段代码假设
;;您已将软件包安装在
;; /usr/local/emacs/site-lisp 目录。适当调整。
(添加到列表'加载路径
(扩展文件名“/usr/local/emacs/site-lisp/jde/lisp”))
(添加到列表'加载路径
(扩展文件名“/usr/local/emacs/site-lisp/semantic”))
(添加到列表'加载路径
(扩展文件名“/usr/local/emacs/site-lisp/speedbar”))
(添加到列表'加载路径
(扩展文件名“/usr/local/emacs/site-lisp/eieio”))
(添加到列表'加载路径
(扩展文件名“/usr/local/emacs/site-lisp/elib”))
;;如果您希望 Emacs 推迟加载 JDEE,直到您打开
;; Java 文件,编辑以下行
(setq defer-loading-jde nil)
;;读书:
;;
;; (setq 延迟加载-jde t)
;;
(如果延迟加载 jde
(程序
(自动加载'jde-mode "jde" "JDE 模式。" t)
(setq 自动模式列表
(附加
'(("\\.java\\'" .jde-模式))
自动模式列表)))
(需要'jde))
;;设置Java源文件的基本缩进
;;到两个空格。
(添加钩子'jde-模式钩子
'( 拉姆达 ( )
(setq c-基本偏移 2)))
;;仅当您想运行时才包含以下内容
;; bash 作为你的 shell。
;;设置 Emacs 以运行 bash 作为其主要 shell。
(setq shell-文件名“bash”)
(setq shell 命令开关“-c”)
(setq 显式 shell 文件名 shell 文件名)
(setenv "SHELL" shell 文件名)
(setq 显式-sh-args '("-login" "-i"))
(if (boundp 'w32-quote-process-args)
(setq w32-quote-process-args ?\")) ;; 仅包含 MS Windows。;; This .emacs file illustrates the minimal setup
;; required to run the JDEE.
;; Set the debug option to enable a backtrace when a
;; problem occurs.
(setq debug-on-error t)
;; Update the Emacs load-path to include the path to
;; the JDEE and its require packages. This code assumes
;; that you have installed the packages in the
;; /usr/local/emacs/site-lisp directory. Adjust appropriately.
(add-to-list 'load-path
(expand-file-name "/usr/local/emacs/site-lisp/jde/lisp"))
(add-to-list 'load-path
(expand-file-name "/usr/local/emacs/site-lisp/semantic"))
(add-to-list 'load-path
(expand-file-name "/usr/local/emacs/site-lisp/speedbar"))
(add-to-list 'load-path
(expand-file-name "/usr/local/emacs/site-lisp/eieio"))
(add-to-list 'load-path
(expand-file-name "/usr/local/emacs/site-lisp/elib"))
;; If you want Emacs to defer loading the JDEE until you open a
;; Java file, edit the following line
(setq defer-loading-jde nil)
;; to read:
;;
;; (setq defer-loading-jde t)
;;
(if defer-loading-jde
(progn
(autoload 'jde-mode "jde" "JDE mode." t)
(setq auto-mode-alist
(append
'(("\\.java\\'" . jde-mode))
auto-mode-alist)))
(require 'jde))
;; Set the basic indentation for Java source files
;; to two spaces.
(add-hook 'jde-mode-hook
'(lambda ( )
(setq c-basic-offset 2)))
;; Include the following only if you want to run
;; bash as your shell.
;; Set up Emacs to run bash as its primary shell.
(setq shell-file-name "bash")
(setq shell-command-switch "-c")
(setq explicit-shell-file-name shell-file-name)
(setenv "SHELL" shell-file-name)
(setq explicit-sh-args '("-login" "-i"))
(if (boundp 'w32-quote-process-args)
(setq w32-quote-process-args ?\")) ;; Include only for MS Windows.当然,您需要确保
add-to-list'load-path行中的路径与您正在使用的实际目录匹配。
Of course, you'll need to make sure the paths in the
add-to-list 'load-path lines
match the actual directories you're using.
编译 JDEE Lisp 文件不是必需的,但正如 第 11 章中的“字节编译 Lisp 文件”中所述,这是一个好主意,可以加快一些操作,包括一般启动时间。 JDEE 使这一步变得简单。安装后,启动 Emacs 并运行Mx jde-compile-jde。您只需运行此命令一次,因此绝对值得。
Compiling the JDEE Lisp files is not required, but as noted in "Byte-Compiling Lisp Files" in Chapter 11, it's a good idea and speeds up several operations including general startup times. The JDEE makes this step simple. After you have it installed, start Emacs and run M-x jde-compile-jde. You run this command only once, so it is definitely worthwhile.
我们需要的最后一步 涵盖的是注册您的 Java 开发工具包。这并不是绝对必要的,但您不想跳过此步骤。如果您在必须测试 JDK 的多个版本的环境中工作,它会特别方便。在 JDEE 中注册所有套件后,您可以通过简单的变量更改在版本之间进行切换。
The last step we need to cover is registering your Java development kits. This is not strictly necessary, but you don't want to skip this step. It is especially handy if you work in an environment where you have to test multiple versions of the JDK. With all of your kits registered in the JDEE, you can switch between versions with a simple variable change.
要注册 JDK,请使用Mxcustomize-variable命令。您需要自定义的变量是jde-jdk-registry。这将使您进入交互式定制屏幕。您可以选择INS(插入)按钮来添加您的JDK的版本号和路径。您可以对要注册的任意多个 JDK 重复该过程。有关 Mac OS X 系统上此类条目的列表,请参见图9-2 。
To register a JDK, use the M-x customize-variable command. The variable you need to customize is jde-jdk-registry. That will land you in the interactive customization screen. You can select the INS (insert) button to add the version number and path of your JDK. You can repeat that process for as many JDKs as you want to register. See Figure 9-2 for a list of such entries on a Mac OS X system.
请务必点击“状态”按钮并保存此状态以供将来的会话使用。完成后您可以单击“完成”按钮,或者直接关闭缓冲区。
Be sure to hit the State button and save this state for future sessions. You can click the Finish button when you're done or just close the buffer.
注册 JDK 后,您可以使用相同的Mxcustomize-variable命令切换到活动版本。这次,编辑jde-jdk变量。系统将提示您选择已注册的版本之一。您可能想也可能不想为将来的会议保存此决定。无论如何,这个变量可以随时编辑。
After you have your JDKs registered, you can switch to the active version using that same M-x customize-variable command. This time, edit the jde-jdk variable. You'll be prompted to choose one of the registered versions. You may or may not want to save this decision for future sessions. In any case, this variable can be edited at any time.
编译功能需要访问 tools.jar文件(或某些JDK 内置的等效文件)。如果 JDEE 编译命令失败并显示有关无法找到tools.jar文件的错误消息,则最好的选择是自定义 JDEE 变量jde-global-classpath。确保该变量包含tools.jar文件。
The compilation feature requires access to the tools.jar file (or the equivalents built-in to some JDKs). If the JDEE compile command fails with an error message about not being able to find the tools.jar file, your best bet is to customize the JDEE variable jde-global-classpath. Make sure that variable includes the tools.jar file.
对于某些没有tools.jar 文件[ 11 ]的系统,您可以从另一台计算机窃取该文件,但通常您只需要正确设置类路径和注册表项即可。自定义表 9-6中的变量应该可以让您无需太多努力即可编译和运行。
For some systems that do not have a tools.jar file[11], you can steal that file from another machine, but usually you just need to get your classpath and registry entries set up correctly. Customizing the variables in Table 9-6 should get you compiling and running without too much effort.
哇!这是一项繁重的工作。但好消息是,一旦完成安装过程,您就可以永远使用 JDEE 的所有出色功能。那么让我们继续了解这些功能吧!
Whew! That was a lot of work. But the good news is that once you've made it through the installation process, you have all the spiffy features of the JDEE forever at your command. So let's get on with the features!
首先,您仍在 Emacs 中,所以 Java 模式(和 C 模式)描述的常用运动命令仍然适用。但是 JDEE 为您的编辑周期添加了两个非常出色的功能:命令完成和类浏览。
First off, you're still in Emacs, so the usual motion commands described for Java mode (and C mode) still apply. But the JDEE adds two really great features to your editing cycle: command completion and class browsing.
命令完成背后的想法是,JDEE(通常)可以预测在 Java 程序中的某些点上哪些方法和变量是有效的选择。例如,如果您开始输入 System。在你的程序中,该时期之后的选择数量是有限的。 JDEE 可以显示这些选择的列表。
The idea behind command completion is that the JDEE can (usually) predict which methods and variables are valid choices to make at certain points in your Java program. For example, if you start typing System. in your program, there are a finite number of choices for what follows that period. JDEE can display a list of those choices.
显示完成列表的命令是Cc Cv C-。 (对于jde-complete),默认显示一个完成菜单。 (您可以通过自定义 jde-complete-function变量来更改该行为。)通过查看jde-global-classpath变量(如果未定义全局类路径,则查看 CLASSPATH 环境变量)中列出的所有类来生成补全。。
The command to show your list of completions is C-c C-v C-. (for jde-complete), which defaults to showing you a menu of completions. (You can change that behavior by customizing the jde-complete-function variable.) The completions are generated by looking at all of the classes listed in the jde-global-classpath variable (or the CLASSPATH environment variable if no global classpath was defined).
可以从 JDE 菜单快速访问类浏览器,并为光标所在的类启动 BeanShell 浏览器。它就像一个上下文相关的文档工具,但功能更强大一些。图 9-3显示了当光标位于“ System”一词上时启动浏览器时所得到的结果。
The class browser can be accessed quickly from the JDE menu and launches a BeanShell browser for the class your cursor was on. It's like a context-sensitive documentation tool, but a bit more powerful. Figure 9-3 shows what you get when starting the browser while your cursor is on the word System.
您还可以使用Mx jde-browse-class-at-point命令启动类浏览器。
You can also launch the class browser with the M-x jde-browse-class-at-point command.
另一个值得指出的编辑时功能是 JDE 菜单中的“代码生成”项。它内置了一些很棒的省时功能,如表 9-7所示。
One other edit-time feature worth pointing out is the Code Generation item in the JDE menu. It has some great timesavers built-in, as shown in Table 9-7.
表 9-7。代码生成菜单选项
Table 9-7. Code Generation menu options
|
击键 Keystrokes |
菜单选项 Menu option (MX命令) (M-x command) |
行动 Action |
|---|---|---|
|
抄送 Cv Cl(小写 L) C-c C-v C-l (lowercase L) |
打印向导( jde-gen-println ) Println Wizard(jde-gen-println) |
提示打印内容并
Prompts for the contents to print and inserts a complete
|
|
抄送 Cv Cz C-c C-v C-z |
导入类( jde-import-find-and-import ) Import Class(jde-import-find-and-import) |
提示输入要导入的(简单)类名,并自动将正确的导入行添加到文件顶部。 Prompts for the (simple) class name to import and automatically adds the proper import line to the top of your file. |
|
抄送 Cv i C-c C-v i |
实现接口( jde-wiz-implement-interface ) Implement Interface(jde-wiz-implement-interface) |
提示您输入要实现的接口的名称。添加任何缺少的导入语句(包括依赖导入,例如方法参数所需的导入)。为接口中的每个方法提供带注释的框架。 Prompts you for the name of the interface to implement. Adds any missing import statements (including dependent imports, such as imports required for method arguments). Provides commented skeletons for each of the methods in the interface. |
其他帮助程序可从 JDE 菜单中获得。生成 Get/Set 对尤其适合使用 JavaBeans 设计模式。只需创建属性列表,然后运行向导即可。它甚至检查您是否已经有一个现有的获取/设置对。如果这样做,它会指出获取/设置对为“现有”并继续传送,以便您可以使用向导来更新现有类。
Other helpers are available from the JDE menu. Generate Get/Set Pairs in particular is great for working with JavaBeans design patterns. Just create your list of attributes and then run the wizard. It even checks to see if you already have an existing get/set pair. If you do, it notes that get/set pair as "existing" and keeps on trucking so you can use the wizard to update existing classes.
编译当前缓冲区 可以使用Cc Cv Cc命令快速完成 。任何错误都会显示在编译缓冲区中。该编译缓冲区还允许您快速导航到编译器发现的任何错误。只需将光标移动到有问题的错误(使用正常的运动命令)并按Enter即可。您会发现自己位于正确的文件中的正确行号上。确实非常方便。
Compiling the current buffer can be done quickly with the C-c C-v C-c command. Any errors show up in the compilation buffer. That compilation buffer also allows you to navigate quickly to any errors that the compiler finds. Simply move your cursor to the error in question (using the normal motion commands) and hit Enter. You'll find yourself in the right file on the right line number. Very handy indeed.
请注意,您还可以 使用Mx jde-ant-build运行ant构建。查看 JDEE 文档或各种jde-ant变量的帮助以获取更多信息。
Note that you can also run ant builds with M-x jde-ant-build. Check out the JDEE documentation or the help for various jde-ant variables for more information.
运行一个有自己main( )
方法的简单程序很容易:只需按Cc Cv Cr即可。该命令执行当前缓冲区(通过打开名为*
full.qualified.ClassName
的执行缓冲区
*)。程序的任何输出都显示在缓冲区中。您可以在缓冲区中移动,就像在普通文本缓冲区中一样。
Running a simple program that has its own main( )
method is easy: just press C-c C-v
C-r. That command executes the current buffer (by opening
an execution buffer named
*
fully.qualified.ClassName
*).
Any output from the program shows in the buffer. You can move around
in the buffer just as you would in a normal text buffer.
当然,如果您正在处理简单测试类以外的任何内容,那么您可能会在一个包中。 Java 对类路径的使用很少为包层次结构的“底部”留下空间。例如,在 package 中
com.oreilly.demo,您希望从包含com
目录的同一目录开始执行,而不是从包含实际 Java 文件的demo目录开始执行。遗憾的是,
demo目录是默认的。
Of course, if you are working on anything other than a simple test
class, you'll probably be in a package.
Java's use of the classpaths rarely leaves room for
being at the "bottom" of a package
hierarchy. For example, in the package
com.oreilly.demo, you want to start execution from
the same directory that contains the com
directory, not from the demo directory that
contains the actual Java files. Regrettably, the
demo directory is the default.
您可以编辑以下变量以使在较大项目中执行更加方便:
You can edit the following variables to make executing in larger projects a bit more convenient:
开始执行的目录
The directory in which execution starts
main( )包含要执行的方法的类的完全限定名称
The fully qualified name of the class that contains the
main( ) method to execute
设置这些值后,您应该能够从任何缓冲区运行应用程序,无论您正在编辑的文件位于哪个目录中。
With those values set, you should be able to run your application from any buffer, regardless of what directory the file you're editing happens to be in.
关于通过 JDEE 运行应用程序的另一个有趣的注意事项:如果由于异常而出现任何堆栈跟踪,您可以使用Cc Cv C-[和 Cc Cv C-]命令(分别向上和向下)导航这些跟踪。同样,Emacs 使从一个界面管理开发项目的很大一部分成为可能。
Another fun note about running your application through the JDEE: if any stack traces appear because of exceptions, you can navigate those traces by using the C-c C-v C-[ and C-c C-v C-] commands (up and down, respectively). Again, Emacs makes it possible to manage quite a large portion of a development project all from one interface.
任何优秀 IDE 的一个关键要素是它 调试器。 JDEE 允许您在与jdb进程交互时留在 Emacs 领域。 JDEE 还附带了自己的调试器,即 JDEbug 应用程序。 JDEbug 更强大,但需要更多的设置工作。
A crucial element in any good IDE is its debugger. The JDEE allows you to stay in the Emacs realm while interacting with the jdb process. The JDEE also comes with its own debugger, the JDEbug application. JDEbug is more powerful but requires more setup effort.
在我们接触任何内容之前,您需要确保您的类在编译时支持调试。否则,当您运行调试器时,很多东西都会显得损坏。
Before we touch anything, you need to make sure that your classes are compiled with support for debugging. Otherwise, many things will appear broken when you run the debugger.
要在编译时添加调试支持,请运行带有 -g选项的javac命令。使用 JDEE,您还可以使用变量jde-compile-option-debug来保存您喜欢的调试的所有变体。如果您通过“自定义”自定义此变量(请参阅第 10 章),只需选择要包含的调试信息的“全部”选项。 (或者,您可以更具体,并从三种类型的调试信息中进行选择:行、变量和源。)
To add debug support when you compile, you run the javac command with the -g option. With the JDEE you can also use the variable jde-compile-option-debug to hold all the variations for debugging you like. If you customize this variable through Custom (see Chapter 10), just choose the "all" option for which debugging information to include. (Optionally, you can be more specific and select from the three types of debug information: Lines, Variables, and Source.)
我们将查看jdb路线,以帮助您入门。您可以通过输入Mx jde-jdb来启动调试会话。控制起始目录和主应用程序类的相同变量也用于调试目的。
We'll look at the jdb route just to get you started. You can start the debug session by typing M-x jde-jdb. The same variables that control the starting directory and main application class are used for debugging purposes.
启动调试器后,您可以通过多种方式控制调试过程。
After you have launched the debugger, you can control the debug process in a number of ways.
直接与缓冲区中的jdb进程交互*debug*。您可以在此处键入运行jdb时通常给出的任何命令。
Interact directly with the jdb
process in the *debug* buffer. Here you can type
any command that you would normally give when running jdb.
使用 Jdb 菜单。您可以使用所有常用的调试选项:单步进入/跳过、继续、切换断点等等。这比第一种方法有更多限制,但如果您是jdb新手,则更容易管理。
Use the Jdb menu. You have all the usual debug options available: step into/over, continue, toggle breakpoint, and so on. This is a bit more limited than the first approach, but easier to manage if you're new to jdb.
当您位于源缓冲区中时使用键盘命令。这些命令比菜单选项更加有限,但可以让您快速访问最常见的任务(即单步执行和断点)。表 9-8显示了在源缓冲区中时可用的命令。
Use keyboard commands while you're in your source buffer. These commands are even more limited than the menu options, but give you really quick access to the most common tasks (namely stepping and break points). Table 9-8 shows the commands that are available while you're in a source buffer.
表 9-8。 JDEE 调试器控件
Table 9-8. JDEE debugger controls
|
击键 Keystrokes |
菜单项 Menu item |
JDB命令 JDB command |
|---|---|---|
|
抄送钙铯 C-c C-a C-s |
步入 Step Into |
步 step |
|
抄送 Ca cn C-c C-a C-n |
跨过 Step Over |
下一个 next |
|
抄送 抄送 C-c C-a C-c |
继续 Continue |
续 cont |
|
CC 钙 Cb C-c C-a C-b |
切换断点 Toggle Breakpoint |
停在/停在/清除 stop in/stop at/clear |
|
抄送 钙 CP C-c C-a C-p |
显示表达式 Display Expression |
打印 |
|
抄送钙镉 C-c C-a C-d |
显示对象 Display Object |
倾倒 dump |
图 9-4显示了一个在调试模式下运行的简单应用程序。请注意上方缓冲区中 Java 源代码左侧的黑色小三角形。这是调试光标,可以让您知道您在文件中的位置。它跟踪您发出的命令,无论是通过直接输入jdb命令、通过菜单选项还是通过键盘。
Figure 9-4 shows a simple application running in debug mode. Notice the small black triangle to the left of the Java source code in the upper buffer. That's the debug cursor that lets you know where you are in the file. It tracks the commands you issue, whether by directly entering jdb commands, by menu option, or through the keyboard.
显然,有很多JDEE 的内容超出了我们在此所能介绍的范围。您下载的软件包附带了一些很好的文档和一些有关基本 JDEE 和各种选项(如调试器)的用户指南。 JDEE 网站 http://jdee.sunsite.dk也是一个很好的信息来源。正如您对 Emacs 软件包所期望的那样,您可以自定义一切。这些自定义设置存储在您的.emacs文件中,因此您可以手动调整它们(或者至少查看它们)。
Clearly, there is a lot more to the JDEE than we can cover here. The package you download comes with some good documentation and several user guides for the basic JDEE and various options like the debuggers. The JDEE web site, at http://jdee.sunsite.dk, is a great source of information, too. As you would expect from an Emacs package, you can customize everything. Those customizations are stored in your .emacs file so you can tweak them by hand (or at least peek at them).
最好的方法是安装 JDEE 并开始用它编码。如果您发现自己说“应该有一种方法可以做到 X”,请拿出文档。很可能有一种方法可以实现某件事——通常有比您希望的更多的选择!
The best approach is to install the JDEE and start coding with it. If you find yourself saying "There should be a way to do X," get out the documentation. Chances are there is a way to do X—usually with more options than you could hope for!
[ 10 ]在我们带您完成安装过程之前,我们应该提到两个注意事项。 XEmacs 内置了 JDEE,尽管它常常已经过时。 TEI-Emacs 是第 8 章中描述的适用于 Linux 和 Windows 的附加组件 ,也包括 JDEE。
[10] Before we take you through the installation process, we should mention two caveats. XEmacs has the JDEE built-in, though it is often out-of-date. TEI-Emacs, an add-on for Linux and Windows described in Chapter 8, also includes the JDEE.
[ 11 ]对于Mac OS X 用户,通常在tools.jar中找到的类已经是标准classes.jar的永久部分,因此它们始终可用——即使tools.jar 不在任何库位置中。
[11] For Mac OS X users, the classes normally found in tools.jar are already a permanent part of the standard classes.jar so they are always available—even though tools.jar isn't in any of the library locations.
Emacs 有 Perl 支持。的确, 就像 Perl 本身一样,有多种方法可以完成任务 - 在本例中,有多种 Perl 模式:经典的 Perl 模式(默认情况下出现)和更流行的 CPerl 模式。
Emacs has Perl support. Indeed, much like Perl itself, there are multiple ways to get things done—in this case, multiple Perl modes: the classic Perl mode (which comes up by default) and the more popular CPerl mode.
您应该有一个内置的 CPerl 模式版本,但您也可以从 CPAN(综合 Perl 存档网络)获取最新版本 在线访问 http://www.cpan.org。
You should have a version of CPerl mode built right in, but you can also pick up the latest release from CPAN (the Comprehensive Perl Archive Network) online at http://www.cpan.org.
您可以将以下几行之一添加到 .emacs文件中,以确保调用 CPerl 模式而不是 Perl 模式
You can add one of the following pairs of lines to your .emacs file to make sure CPerl mode is invoked rather than Perl mode
;;加载 perl 文件的 cperl 模式 (fset 'perl-mode 'cperl-mode) ;;或者也许使用别名 (defalias 'perl-mode 'cperl-mode)
;; load cperl-mode for perl files (fset 'perl-mode 'cperl-mode) ;; or maybe use an alias (defalias 'perl-mode 'cperl-mode)
就运动和其他编程语言功能而言, CPerl 模式与cc 模式非常相似。它还包括有趣的调试操作。您可以使用Mx cperl-db启动调试器 。系统将提示您验证调试器命令,然后进入分屏模式。一个缓冲区允许您 使用您习惯在 Perl 调试器中使用的所有常规命令来驱动正常的perldb环境。
CPerl mode is mostly like cc-mode with respect to motion and other programming language features. It also includes fun debug operations. You can start the debugger with M-x cperl-db. You'll be prompted to verify the debugger command and then be dropped into a split-screen mode. One buffer allows you to drive the normal perldb environment with all the regular commands you're accustomed to using in the Perl debugger.
另一个缓冲区显示您的脚本并在您通过调试器工作时跟随。当您在另一个缓冲区中发出命令时,它会跟踪您将要执行的行。令人惊奇的是,您在开发脚本时很快就依赖于此类工具。如果您以前从未这样做过,那么值得尝试一下。
The other buffer shows your script and follows along as you work through the debugger. It tracks the line you're about to execute as you issue commands in the other buffer. It's amazing how quickly you grow to depend on having such tools available while you're developing scripts. It is worth trying out if you've never done it before.
我们想在这里提到 Perl 模式的一个重要原因是强调一些注意事项。 Perl 是一种表现力极强的语言,与任何其他计算机语言相比,它更类似于人类语言中的习语。这种表达能力可能会导致问题——尤其是在考虑正则表达式的表达能力时。
A big reason we wanted to mention Perl mode here is to highlight a few caveats. Perl is an amazingly expressive language much more akin to the idioms found in human languages than just about any other computer language out there. That expressiveness can cause problems—especially when considering the expressiveness of regular expressions.
Perl 支持各种“有趣的”变量名称,例如$'和
$/。 CPerl 模式使用语法表来帮助理解大多数 Perl 的奇怪且偶尔具有破坏性的用语。旧的 Perl 模式没有这样的技巧,并且在字体锁定和缩进领域的许多情况下都会受到影响。这是跳入 CPerl 模式的主要原因之一。
Perl supports all sorts of "funny"
variable names like $' and
$/. CPerl mode boasts the use of a syntax
table to help understand most of Perl's odd and
occasionally disruptive verbiage. The older Perl mode has no such
trick up its sleeves and suffers under many circumstances in the
font-lock and indentation realms. This is one of the main reasons to
make the leap into CPerl mode.
不过,即使有了这个语法表,您也可能会发现一些变量和字符串的组合让 Emacs 头疼。有时重组代码会有帮助,有时则没有。需要记住的重要一点是它根本不会损害您的程序。它可能会降低可读性,但脚本本身应该运行得很好。如果没有,您可以随时启动调试器来找出原因!
Even with that syntax table, though, you'll probably find some combinations of variables and strings that give Emacs headaches. Sometimes restructuring your code will help, sometimes not. The important thing to remember is that it won't harm your program at all. It might make things a bit less readable, but the script itself should run just fine. And if it doesn't, you can always launch the debugger to find out why!
以下是为 Perl 程序员提供的一些关于.emacs 的想法。这些行选择cperl-mode作为默认值,并确保语法突出显示已打开。这些行也会打开 折叠(下面代码片段中的轮廓次要模式)。折叠允许您“隐藏”代码块,例如函数主体“折叠”到名称中的函数。这可以让您更轻松地掌握文件中发生的所有事情。尝试一下——它会让人上瘾!
Here are some parting .emacs thoughts for you Perl programmers. These lines select cperl-mode as the default and make sure the syntax highlighting is turned on. These lines also turn on folding (outline-minor-mode in the snippet below). Folding allows you to "hide" chunks of your code, such as functions where the body of the function is "folded" into the name. That can make it easier to get a grip on everything that is going on in the file. Try it—it can become addictive!
;;打开全局突出显示 (全局字体锁定模式 t) ;;自动加载 perl 文件的 cperl 模式 (fset 'perl-mode 'cperl-mode) ;;加载文件时仅显示顶层节点 (add-hook 'cperl-mode-hook 'hide-body) ;;使用 cperl 概述次要模式 (add-hook 'cperl-mode-hook 'outline-minor-mode) ;;将大纲命令的前缀从 Cc @ 更改为 Cc Co (setq 大纲次要模式前缀“\C-co”) (加载文件“cperl-mode.el”)
;; Turn on highlighting globally (global-font-lock-mode t) ;; automatically load cperl-mode for perl files (fset 'perl-mode 'cperl-mode) ;; show only the toplevel nodes when loading a file (add-hook 'cperl-mode-hook 'hide-body) ;; outline minor mode with cperl (add-hook 'cperl-mode-hook 'outline-minor-mode) ;; Change the prefix for outline commands from C-c @ to C-c C-o (setq outline-minor-mode-prefix "\C-co") (load-file "cperl-mode.el")
对于你们数据库人员来说 在那里,您甚至可以通过 Emacs 运行交互式 SQL 会话。您可以使用正常的运动命令浏览 SQL 命令历史记录,甚至可以在任何缓冲区中创建复杂的 SQL 语句,然后将它们传送到交互区域进行调试。
For you database folks out there, you can even run interactive SQL sessions through Emacs. You can navigate through your SQL command history using normal motion commands and even create complex SQL statements in any buffer and then shuttle them off to the interactive area for debugging.
在开始使用 SQL 查询之前,您确实需要做好一些准备工作。大多数 SQL 交互模式都需要针对其特定数据库的实际客户端应用程序。例如,我们使用MySQL服务器。我们必须mysql在要使用 SQL 模式的任何系统上安装 MySQL 客户端程序(至少)。尽管MySQL版本的SQL模式是内置的,但我们仍然需要访问真实的客户端。对于您希望访问的每种类型的数据库都是如此。
Before we get started with SQL queries, you do need to have a few
things in place. Most of the SQL interaction modes require an actual
client application for their particular database. For example, we use
the MySQL server. We have to install the MySQL client programs
(mysql, at a minimum) on any system where we want
to use SQL mode. Even though the MySQL version of SQL mode is
built-in, we still need access to a real client. This is true for
every type of database you expect to access.
说到与数据库通信,您还必须掌握通信的基础知识。您需要具有对相关服务器的网络访问权限。您还需要拥有有效的用户名和密码才能连接到该服务器。在 Emacs 中进入 SQL 模式之前,一个好的规则是确保您可以从您的计算机连接数据库服务器并与之交互。如果它在终端窗口或其他客户端应用程序中运行,您可以使其在 Emacs 中运行。
And speaking of communicating with the database, you must also have the basics of communication taken care of. You need to have network access to the server in question. You also need to have a valid username and password for connecting to that server. A good rule before jumping into SQL mode in Emacs is to make sure you can connect and interact with your database server from your machine. If it works from a terminal window or other client application, you can make it work in Emacs.
最后要记住的一件事:Emacs 中的各种 SQL 模式只是助手,因此您无法使用它们做任何普通数据库客户端无法做的事情。你不会神奇地以每个人的薪水进入那个受限的桌子。对不起。即便如此,如果可能的话,留在 Emacs 中会更方便,所以让我们继续前进。
One last thing to remember: the various SQL modes in Emacs are just helpers, so you can't do anything with them that you couldn't do with your normal database client. You won't magically have access to that restricted table with everyone's salaries. Sorry. Even so, it's just more convenient to stay in Emacs when possible, so let's forge ahead.
你会发现两种模式 处理SQL的操作。交互模式允许您直接与数据库服务器通信并运行命令并立即查看其输出。编辑模式允许您构建(和编辑)更复杂的命令。如果需要,您可以让编辑缓冲区将其自身的一部分发送到交互式会话以进行测试和验证。
You'll find two modes of operation for dealing with SQL. The interactive mode lets you communicate directly with a database server and run commands and view their output immediately. The editing mode allows you to build up (and edit) more complex commands. If you want, you can have the editing buffer send parts of itself to the interactive session for testing and verification.
通过键入Mx sql-mysql (或者更确切地说,表 9-9中所示的您自己的交互模式变体)来启动交互模式。
Start the interactive mode by typing M-x sql-mysql (or rather, your own variant of the interactive modes shown in Table 9-9).
表 9-9。用于进入特定于数据库的 SQL 模式的命令
Table 9-9. Commands for entering database-specific SQL modes
|
SQL-DB2 sql-db2 |
sql-linter sql-linter |
sql-postgres sql-postgres |
|
sql-informix sql-informix |
sql-ms(微软) sql-ms (Microsoft) |
sql-solid sql-solid |
|
sql-ingres sql-ingres |
sql mysql sql-mysql |
SQLite sql-sqlite |
|
sql-interbase sql-interbase |
sql-oracle sql-oracle |
sql-sybase sql-sybase |
系统将提示您输入用户名和密码、要使用的数据库或目录以及要联系的服务器等信息。但请记住先决条件;许多模式要求您有一个可用的普通命令行客户端。该模式只是在这些客户端之上提供一个智能层。
You'll be prompted for things like your username and password, the database or catalog to use, and the server to contact. Remember the prerequisites, though; many modes require that you have a normal command-line client available. The mode simply supplies an intelligent layer on top of those clients.
连接后,只需键入服务器可以理解的普通 SQL 命令即可。大多数交互式客户端都有某种类型的“行尾”标记,让系统知道何时发送已完成的命令。例如,在 MySQL 中,您可以用分号 (;) 或\g序列结束语句。
After you get connected, just type normal SQL commands that your server understands. Most interactive clients have some type of "end-of-line" marker to let the system know when to send a completed command. In MySQL, for example, you can end statements with a semicolon (;) or the \g sequence.
Emacs 将这些命令保存在历史缓冲区中,以便您可以重新访问它们。Mp和Mn允许您分别导航到上一个和下一个命令。 (Cp和 Cn只是允许您按照预期在缓冲区中移动。)
Emacs keeps these commands in a history buffer for you so that you can revisit them. M-p and M-n allow you navigate to previous and next commands respectively. (C-p and C-n simply allow you to move around in the buffer as you would expect.)
也可以放一个缓冲区 使用Mx sql-mode直接进入 SQL 模式。这为 SQL 语句的移动和组合提供了一些帮助,但主要是为了让您构建复杂的语句,然后将它们发送到交互式缓冲区以供执行。表 9-10显示了如何将缓冲区的各个段发送到数据库。
You can also put a buffer directly into SQL mode with M-x sql-mode. This provides some assistance for motion and composition of SQL statements, but mostly it's there to let you build complex statements and then ship them to the interactive buffer for execution. Table 9-10 shows how to send various segments of the buffer to the database.
表 9-10。 SQL模式发送命令
Table 9-10. SQL mode send commands
|
按键 Keystroke |
命令名称 Command name |
行动 Action |
|---|---|---|
|
抄送抄送 C-c C-c |
sql 发送段落 sql-send-paragraph |
发送光标所在的段落。段落由特定的数据库客户端定义。例如,对于sql-mysql进程,一个段落以 select 或 update 等语句开头,并以分号结尾。任意数量的线路都可以介入。 Send the paragraph the cursor is on. A paragraph is defined by the particular database client. For the sql-mysql process, for example, a paragraph begins with a statement like select or update and ends with a semicolon. Any number of lines can intervene. |
|
CC铬 C-c C-r |
sql 发送区域 sql-send-region |
发送标记的区域。 Send the marked region. |
|
抄送 抄送 C-c C-b |
sql 发送缓冲区 sql-send-buffer |
发送整个缓冲区。 Send the entire buffer. |
所有这些发送命令的输出都显示在交互式缓冲区中。编辑缓冲区中没有任何变化,因此您可以随意尝试。这就是这些模式的用途!
The output of all of these send commands shows up in your interactive buffer. Nothing changes in the editing buffer so you should feel free to experiment. That's what these modes are here for!
Emacs 有三种 Lisp 模式,列出 这里是它们的命令名称:
Emacs has three Lisp modes, listed here by their command names:
用于编辑 Emacs Lisp 代码,如第 11 章所述(文件名.emacs或后缀.el)。
Used for editing Emacs Lisp code, as covered in Chapter 11 (filename .emacs or suffix .el).
用于编辑用于另一个 Lisp 系统的 Lisp 代码(后缀 .l或.lisp)。
Used for editing Lisp code intended for another Lisp system (suffix .l or .lisp).
用于编辑和运行 Emacs Lisp 代码。
Used for editing and running Emacs Lisp code.
所有三种模式都具有相同的基本功能;它们的区别仅在于对运行 Lisp 代码的支持。
All three modes have the same basic functionality; they differ only in the support they give to running Lisp code.
所有三种 Lisp 模式都理解所有语言模式共有的基本语法元素。此外,它们还具有适用于 S 表达式、列表和 defun 等更高级语法概念的各种命令。S 表达式(或语法表达式)是任何语法正确的 Lisp 表达式,可以是原子(数字、符号、变量等),也可以是带括号的列表。 列表是 S 表达式的特例, defuns(函数定义)是列表的特例。有几个命令处理这些语法概念;您很可能会对其中的一部分感到满意。
All three Lisp modes understand the basic syntax elements common to all language modes. In addition, they have various commands that apply to the more advanced syntactic concepts of S-expressions, lists, and defuns. An S-expression (or syntactic expression) is any syntactically correct Lisp expression, be it an atom (number, symbol, variable, etc.), or parenthesized list. Lists are special cases of S-expressions, and defuns (function definitions) are special cases of lists. Several commands deal with these syntactic concepts; you will most likely become comfortable with a subset of them.
表 9-11显示了以下命令 处理 S 表达式。
Table 9-11 shows the commands that handle S-expressions.
表 9-11。 S-表达式命令
Table 9-11. S-expression commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CMb C-M-b |
后向性别 backward-sexp |
向后移动一个 S 表达式。 Move backward by one S-expression. |
|
CMf C-M-f |
前向性别 forward-sexp |
向前移动一个 S 表达式。 Move forward by one S-expression. |
|
CMt C-M-t |
转置性别 transpose-sexps |
调换光标周围的两个 S 表达式。 Transpose the two S-expressions around the cursor. |
|
厘米-@ C-M-@ |
标记性别 mark-sexp |
将标记设置为当前 S 表达式的末尾;将光标设置到开头。 Set mark to the end of the current S-expression; set the cursor to the beginning. |
|
CMk C-M-k |
杀戮性爱 kill-sexp |
删除光标后面的 S 表达式。 Delete the S-expression following the cursor. |
|
(没有任何) (none) |
向后杀性 backward-kill-sexp |
删除光标前面的 S 表达式。 Delete the S-expression preceding the cursor. |
由于 S 表达式可以是各种各样的东西,因此处理 S 表达式的命令的操作由调用它们时光标所在的位置决定。如果您的光标位于(或前面的空格上,则相关的 S 表达式将被视为以(开头的列表。如果您的光标位于某个其他字符上,例如字母或数字(或前面的空格) ),S-表达式被视为一个原子(符号、变量或常量)。
Since an S-expression can be a wide variety of things, the actions of commands that handle S-expressions are determined by where your cursor is when you invoke them. If your cursor is on a ( or on a space preceding one, the S-expression in question is taken to be the list that starts with that (. If your cursor is on some other character such as a letter or number (or preceding whitespace), the S-expression is taken to be an atom (symbol, variable, or constant).
例如,假设您的光标位于以下位置:
For example, suppose your cursor is in this position:
(玛丽·鲍勃(戴夫(皮特))编辑)
(mary bob (dave (pete)) ed)
如果您输入CMf,光标将像这样移动:
If you type C-M-f, the cursor moves like this:
(玛丽·鲍勃(戴夫(皮特))编辑)
(mary bob (dave (pete)) ed)
也就是说,光标向前移动经过 S 表达式(dave (pete)),它是一个列表。但是,假设您的光标定位如下:
That is, the cursor moves forward past the S-expression (dave (pete)), which is a list. However, say your cursor is positioned like this:
(玛丽·鲍勃(戴夫(皮特))编辑)
(mary bob (dave (pete)) ed)
当您输入CMf时,它会移至此处:
When you type C-M-f, it moves here:
(玛丽·鲍勃(戴夫(皮特))编辑)
(mary bob (dave (pete)) ed)
在本例中,S 表达式是原子bob。
In this case, the S-expression is the atom bob.
列表中移动的命令如表 9-12所示。
The commands moving in lists are shown in Table 9-12.
表 9-12。用于在列表中移动的命令
Table 9-12. Commands for moving in lists
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
锰 C-M-n |
转发列表 forward-list |
向前移动一个列表。 Move forward by one list. |
|
CMp C-M-p |
向后列表 backward-list |
向后移动一个列表。 Move backward by one list. |
|
CMd C-M-d |
下列表 down-list |
向前和向下移动一级括号。 Move forward and down one parenthesis level. |
|
(没有任何) (none) |
上行列表 up-list |
向前移出一个括号级别。 Move forward out of one parenthesis level. |
|
CMu C-M-u |
向后向上列表 backward-up-list |
向后移出一个括号级别。 Move backward out of one parenthesis level. |
作为一种助记工具,您可以将列表视为类似于线条,将 S 表达式视为类似于字符;因此,Cn和Cp 出现在列表运动命令中,而Cf和Cb 出现在 S 表达式运动命令中。CMn和CMp 的工作方式分别与CMf和CMb类似,不同之处在于您必须定位光标,以便在其前面或后面有一个列表可以移动,也就是说,后面必须有一个左括号或右括号,或在光标之前。如果没有括号,Emacs 会发出错误信号。例如,如果您的光标定位如下:
As a mnemonic device, you can think of lists as analogous to lines and S-expressions as analogous to characters; thus, C-n and C-p appear in list motion commands, whereas C-f and C-b appear in S-expression motion commands. C-M-n and C-M-p work similarly to C-M-f and C-M-b, respectively, except that you must position the cursor so that there is a list in front or back of it to move across—that is, there must be an opening or closing parenthesis on, after, or before the cursor. If there is no parenthesis, Emacs signals an error. For example, if your cursor is positioned like this:
(弗雷德·鲍勃(戴夫(pe t e))编辑)
(fred bob (dave (pete)) ed)
当你输入CMn时,Emacs 会抱怨以下消息:
and you type C-M-n, Emacs complains with the message:
包含表达式提前结束
Containing expression ends prematurely
但是,如果您的光标在这里:
However, if your cursor is here:
(弗雷德·鲍勃(戴夫(皮特))编辑)(fred bob (dave (pete)) ed)“下一个列表”实际上是 (dave (pete)) ,如果您输入CMn,光标最终会像这样:
the "next list" is actually (dave (pete)), and the cursor ends up like this if you type C-M-n:
(弗雷德·鲍勃(戴夫(皮特))编辑)
(fred bob (dave (pete)) ed)
向上或向下移动列表的命令使您能够进入或离开列表。例如,假设您的光标在这里:
The commands for moving up or down lists enable you to get inside or outside them. For example, say your cursor is here:
(弗雷德·鲍勃(戴夫(皮特))编辑) (fred bob (dave (pete)) ed)输入CMd将光标移至此处:
typing C-M-d moves the cursor here:
(f红鲍勃(戴夫(皮特))编辑)(fred bob (dave (pete)) ed)这是结果,因为fred是其封闭列表之后的下一级。再次输入CMd会得到以下结果:
This is the result because fred is the next level down after its enclosing list. Typing C-M-d again has this result:
(弗雷德·鲍勃(戴夫(皮特))编辑)(fred bob (dave (pete)) ed)您现在位于列表中(dave (pete))。此时,键入CMu 的作用与CMd的作用相反:它将光标向后移动到两个列表之外。但如果您输入Mx up-list Enter,您将向前移动并向外移动,结果如下:
You are now inside the list (dave (pete)). At this point, typing C-M-u does the opposite of what C-M-d does: it moves the cursor back and outside of the two lists. But if you type M-x up-list Enter, you will move forward as well as out, resulting in this:
(弗雷德·鲍勃(戴夫(皮特))编辑)
(fred bob (dave (pete)) ed)
表 9-13中列出的 defuns 命令更加简单。
The commands for defuns listed in Table 9-13 are more straightforward.
表 9-13。使用函数的命令
Table 9-13. Commands for working with functions
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CM C-M-a |
开始的乐趣 beginning-of-defun |
移至当前函数的开头。 Move to the beginning of the current function. |
|
CM C-M-e |
结束乐趣 end-of-defun |
移至当前函数的末尾。 Move to the end of the current function. |
|
CMh C-M-h |
马克德芬 mark-defun |
将光标置于函数开头,将标记置于函数末尾。 Put the cursor at the beginning of the function, put the mark at the end. |
仅当启动当前函数的(defun位于行首时,这些命令才能正常工作。
These commands work properly only when the (defun that starts the current function is at the beginning of a line.
Lisp 模式提供“闪烁” 匹配左括号;如果匹配的括号位于当前窗口之外,则它所在的行将出现在迷你缓冲区中。 Lisp 模式还通过Tab键和Cj提供换行和缩进的缩进(Lisp 交互模式除外,本章稍后将介绍)。 Lisp 模式支持的缩进样式“了解”很多有关 Lisp 关键字和列表语法的知识;不幸的是,它不容易定制。[ 12 ]
The Lisp modes provide "flashing" of matching left parentheses; if the matching parenthesis is outside of the current window, the line it is on appears in the minibuffer. The Lisp modes also provide indentation via the Tab key and C-j for newline-and-indent (except in Lisp interaction mode, described later in this chapter). The indentation style supported by the Lisp modes "knows" a lot about Lisp keywords and list syntax; unfortunately, it is not easily customized.[12]
下面是一个示例,相当于本章前面所示的“times”C 函数的 Lisp,它说明了缩进样式:
Here is an example, a Lisp equivalent of the "times" C function shown earlier in the chapter, that illustrates the indentation style:
(解除时间(xy)
(让((i 0)
(结果 0))
(同时 (< ix)
(setq 结果 (+ 结果 y)
我(1+我)))
结果))(defun times (x y)
(let ((i 0)
(result 0))
(while (< i x)
(setq result (+ result y)
i (1+ i)))
result))基本缩进值为2;每当下一行的代码在嵌套中向下一级时,就会使用该值。例如,函数体在包含defun的行之后缩进 2。(while ... and result))行相对于let缩进 2,因为它们是let引入的块的主体。
The basic indentation value is 2; this value is used whenever code on the next line goes down a level in nesting. For example, the body of the function, after the line containing defun, is indented by 2. The (while... and result)) lines are indented by 2 with respect to the let because they are the body of the block let introduces.
像defun、let和while 这样的东西都是函数调用,尽管它们的作用类似于关键字。函数调用的缩进约定是,如果在函数名称和第一个参数出现的行之后的行上有参数,则附加参数与第一个参数对齐。换句话说,其形式如下:
Things like defun, let, and while are function calls, even though they act like keywords. The indentation convention for function calls is that if there are arguments on lines after the line where the function name and first argument appear, the additional arguments line up with the first one. In other words, this has the form:
(函数名称 arg1
精氨酸2
精氨酸3
...)(function-name arg1
arg2
arg3
...)前面函数中setq的多个参数提供了另一个示例。
The multiple arguments to setq in the preceding function provide another example of this.
然而,该行的缩进(结果 0)表明,对于不是函数调用的列表,会发生一些不同的情况。所讨论的列表实际上是 ((i 0) (result 0)),它是一个包含两个元素的列表(两者也是列表)。 Lisp 模式支持的缩进样式将这两个元素对齐。
However, the indentation of the line (result 0) shows that something a bit different happens with lists that are not function calls. The list in question is actually ((i 0) (result 0)), which is a list with two elements (both of which are also lists). The indentation style supported by the Lisp modes lines up these two elements.
尽管类似关键字的术语(如let和while) 实际上是函数调用,但 Lisp 模式“理解”这些函数,为它们设置了特殊的缩进约定。例如,如果我们将 while 循环的条件放在单独的行上并按Tab 键正确缩进,则结果将是:
Even though keyword-like terms such as let and while are actually function calls, the Lisp modes "understand" these functions to the extent that special indentation conventions are set up for them. For example, if we were to put the condition for the while-loop on a separate line and press Tab to indent it properly, the result would be:
(尽管
(< 九)
(setq 结果 (+ 结果 y)
我(1+我))) (while
(< i x)
(setq result (+ result y)
i (1+ i)))if和 cond控制结构也会发生类似的情况;第 11 章包含正确缩进的示例。
Similar things happen with if and cond control structures; Chapter 11 contains properly indented examples.
关于缩进约定的另一点评论是:Lisp 模式适合将多个右括号放在同一行并紧接着彼此的样式,而不是放在单独的行上。例如,行i (1+ i)))包含右括号,分别关闭 1+函数、setq和while。如果您愿意,可以将右括号放在单独的行上,但如果按 Tab 键缩进它们,它们将无法与匹配的左括号正确对齐;你必须手动缩进它们。
Another remark about indentation conventions: the Lisp modes are geared toward a style in which multiple right parentheses are put on the same line immediately following each other, instead of on separate lines. For example, the line i (1+ i))) contains right parentheses that close off the 1+ function, the setq, and the while respectively. If you prefer, you can put your closing parentheses on separate lines, but if you press Tab to indent them, they won't line up properly with their matching open parentheses; you have to indent them manually.
除了用于缩进的Tab和Cj命令之外,Lisp 模式还支持命令CMq(用于 indent-sexp),该命令缩进 S 表达式中光标后面的每一行。例如,您可以使用此命令来缩进整个函数定义:只需将光标放在 defun 之前并输入CMq即可。
In addition to the Tab and C-j commands for indentation, the Lisp modes support the command C-M-q (for indent-sexp), which indents every line in the S-expression just following the cursor. You can use this command, for example, to indent an entire function definition: just put the cursor right before the defun and type C-M-q.
Lisp 模式中的注释被处理 通过通用注释命令M-;,它缩进到注释列 (或者,如果该列中有文本,则在最后一个字符后面一个空格),插入一个分号,并将光标放在它前面。如果您希望注释占据整行(或从comment-column以外的任何位置开始),则必须移至您希望注释开始的位置并自行键入分号。请注意,如果您在仅包含注释的任何行上按Tab,注释将移至comment-column。要解决此问题,请使用两个或多个分号;这样做会导致Tab 将注释保留在原处。 Lisp 模式还支持本章前面讨论的其他注释命令,包括 将注释扩展到另一行的Mj和删除单行注释的Mx Kill-comment Enter 。这些功能对于所有三种 Lisp 模式都是通用的;接下来,我们讨论每个的独特功能。
Comments in the Lisp modes are handled by the universal comment command M-;, which indents out to comment-column (or, if there is text at that column, one space past the last character), inserts a semicolon, and puts the cursor just past it. If you want a comment to occupy an entire line (or to start anywhere other than at comment-column), you must move to where you want the comment to start and type the semicolon yourself. Note that if you press Tab on any line that contains only a comment, the comment moves out to comment-column. To get around this, use two or more semicolons; doing so causes Tab to leave the comments where they are. The Lisp modes also support the other comment commands discussed earlier in the chapter, including M-j to extend a comment to another line and M-x kill-comment Enter to get rid of a single-line comment. These features are common to all three Lisp modes; next, we discuss the features unique to each.
Emacs Lisp模式被设计与要在 Emacs 本身内运行的代码一起使用,因此它有助于运行您键入的代码。 Lisp 是一种解释型(而不是纯编译型)语言,因此可能会模糊 Lisp 编程的写入阶段和运行/调试阶段之间的界限; Emacs Lisp 模式充分利用了这个机会,而 Lisp 交互模式则走得更远,我们稍后会看到。在 Emacs Lisp 模式下,命令CMx ( eval-defun ) 选取光标周围或之后的函数定义并对其求值,这意味着它会解析函数并存储它,以便 Emacs 在调用该函数时“了解”该函数。
Emacs Lisp mode was designed to be used with code meant to run within Emacs itself, so it facilitates running the code you type. Lisp is an interpreted (as opposed to purely compiled) language, so it is possible to blur the line between the write and run/debug phases of Lisp programming; Emacs Lisp mode takes some advantage of this opportunity, whereas Lisp interaction mode goes even further, as we'll see later. In Emacs Lisp mode, the command C-M-x (eval-defun) picks up the function definition around or after the cursor and evaluates it, meaning that it parses the function and stores it so that Emacs "knows" about the function when you invoke it.
Emacs Lisp 模式还包括命令M-Tab(用于lisp-complete-symbol),[ 13 ],它对光标前面的符号(变量、函数名等)执行补全,如第 14 章所述。因此,您可以为符号键入最短的明确前缀,然后输入M-Tab,Emacs 会尽力为您完成符号的名称。如果它完成了符号名称,您就可以继续您正在做的事情。如果没有,则说明您没有提供明确的前缀。您可以输入更多字符(以进一步消除歧义),也可以再次输入M-Tab,然后会弹出一个显示选项的帮助窗口。然后您可以输入更多字符并自行完成该符号,或者您可以再次尝试完成。
Emacs Lisp mode also includes the command M-Tab (for lisp-complete-symbol),[13] which performs completion on the symbol (variable, function name, etc.) preceding the cursor, as described in Chapter 14. Thus, you can type the shortest unambiguous prefix for the symbol, followed by M-Tab, and Emacs tries to complete the symbol's name for you as far as it can. If it completes the symbol name, you can go on with whatever you are doing. If it doesn't, you haven't provided an unambiguous prefix. You can type more characters (to disambiguate further), or you can type M-Tab again, and a help window showing the choices pops up. Then you can type more characters and complete the symbol yourself, or you can try for completion again.
Lisp 模式(与 Emacs Lisp 模式相反)适用于除 Emacs Lisp 解释器之外的 Lisp 处理器。因此,它包含一些用于连接外部 Lisp 解释器的命令。 Lisp 模式命令Cc Cz ( run-lisp ) 将系统的 Lisp 解释器作为子进程启动,并*lisp*为输入和输出创建缓冲区(带有关联的窗口)。[ 14 ]如果 Lisp 子进程已经存在,Cc Cz将使用它而不是创建第二个。您可以通过将光标放在函数定义内的任意位置并使用CMx(在本例中代表lisp-send-defun )来将函数定义发送到 Lisp 子进程。此过程使 Lisp 解释器能够识别您定义的函数,以便您稍后可以调用它们。
Lisp mode (as opposed to Emacs Lisp mode) is meant for use with Lisp
processors other than the Emacs Lisp interpreter. Therefore it
includes a couple of commands for interfacing to an external Lisp
interpreter. The Lisp mode command C-c
C-z (run-lisp) starts up
your system's Lisp interpreter as a subprocess and
creates the *lisp* buffer (with an associated
window) for input and output.[14] If a Lisp subprocess
already exists, C-c C-z uses it
rather than creating a second one. You can send function definitions
to the Lisp subprocess by putting the cursor anywhere within a
function's definition and using C-M-x, which in this case stands for lisp-send-defun. This procedure causes the
functions you define to become known to the Lisp interpreter so that
you can invoke them later.
Emacs Lisp 模式可能是最好的 如果您正在编辑 Emacs Lisp 代码的整个文件,例如,如果您正在编写自己的模式(如第 11 章所述)或修改现有模式,则可以使用该工具。但是,如果您正在编辑 Lisp 代码的“小”片段(例如,对 .emacs文件进行添加或修改),Emacs 具有更强大的功能,您可以使用这些功能来进一步模糊编写和运行代码之间的界限。
Emacs Lisp mode is probably the best thing to use if you are editing entire files of Emacs Lisp code, for example, if you are programming your own mode (as described in Chapter 11) or modifying an existing one. However, if you are editing "little" pieces of Lisp code (for example, making additions or modifications to your .emacs file), Emacs has more powerful features you can use that further blur the line between writing and running code.
其中第一个是命令M- : (对于eval-expression)。该命令使您能够在迷你缓冲区中键入任何类型的单行 Lisp 表达式;计算表达式,并将结果打印在迷你缓冲区中。这是检查 Emacs 变量值和试验未绑定到键或需要参数的“内部”Emacs 函数的极好、快速的方法。您可以在使用eval-expression时使用符号补全命令M-Tab。
The first of these is the command M-: (for eval-expression). This command enables you to type a one-line Lisp expression of any kind in the minibuffer; the expression is evaluated, and the result is printed in the minibuffer. This is an excellent, quick way to check the values of Emacs variables and to experiment with "internal" Emacs functions that aren't bound to keys or that require arguments. You can use the symbol completion command M-Tab while you are using eval-expression.
不幸的是(或者幸运的是,这取决于你的观点),Emacs 通常不允许你使用eval-expression。如果您尝试按M- :,您将看到该消息loading
novice . . 。在迷你缓冲区中。然后会弹出一个窗口,其中包含一条消息,“您并不是真的想输入这个,是吗?”您将获得三个选项:按Space仅尝试该命令一次,按y尝试并启用它以供将来使用而不询问任何问题,或按 n不执行任何操作。
Unfortunately (or fortunately, depending on your point of view),
Emacs doesn't normally let you use eval-expression. If you try pressing M-:, you will see the message loading
novice . . . in the minibuffer. Then a window pops up with
a message on the order of, "You
didn't really mean to type that, did
you?" You get three options: press Space to try the command only once, y to try it and enable it for future use with
no questions asked, or n to do
nothing.
如果您想使用eval-expression,请输入y。该命令实际上会导致以下行被放入您的 .emacs文件中:
If you want to use eval-expression, type y. This command actually results in the following line being put in your .emacs file:
(将“eval-表达式”禁用为零)
(put 'eval-expression 'disabled nil)
如果您是一位知识渊博的 Lisp 程序员,您就会明白此添加将符号eval-expression的属性禁用设置为nil。换句话说,Emacs 认为某些命令对于新手用户是禁止的,因此允许禁用命令。如果您想跳过整个过程并仅使用 eval-expression,只需将上面的行放入您的.emacs文件中(确保包含单引号)。
If you are a knowledgeable Lisp programmer, you will understand that this addition sets the property disabled of the symbol eval-expression to nil. In other words, Emacs considers certain commands to be verboten to novice users and thus allows commands to be disabled. If you want to skip this entire procedure and just use eval-expression, simply put the above line in your .emacs file yourself (make sure you include the single quotes).
另一个帮助您练习 Emacs Lisp 代码的功能是Cx Ce(用于eval-last-sexp)。该命令运行光标所在的 Lisp 行并在迷你缓冲区中打印其值。 Cx Ce对于测试 Emacs Lisp 文件中的单行代码非常方便。
Another feature that helps you exercise Emacs Lisp code is C-x C-e (for eval-last-sexp). This command runs the line of Lisp that your cursor is on and prints its value in the minibuffer. C-x C-e is handy for testing single lines of code in an Emacs Lisp file.
一个更强大的功能是
Lisp交互模式。这是默认缓冲区所处的模式*scratch*。没有后缀的文件名通常会导致 Emacs 进入 Lisp 交互模式,尽管您可以使用变量auto-mode-alist更改此模式,这在本章前面和第 10 章中进行了详细介绍。。您还可以通过输入Mx lisp-interaction-mode Enter将任何缓冲区置于 Lisp 交互模式中;要创建额外的 Lisp 交互缓冲区,只需输入Cx b(用于switch-to-buffer),提供缓冲区名称,然后将其置于 Lisp 交互模式。
An even more powerful feature is
Lisp interaction mode. This is the mode the
default buffer *scratch* is in. Filenames with no
suffixes normally cause Emacs to go into Lisp interaction mode,
though you can change this using the variable auto-mode-alist, described earlier in this
chapter and in more detail in Chapter 10. You
can also put any buffer in Lisp interaction mode by typing M-x lisp-interaction-mode Enter; to create an
extra Lisp interaction buffer, just type C-x
b (for switch-to-buffer),
supply a buffer name, and put it in Lisp interaction mode.
Lisp 交互模式与 Emacs Lisp 模式相同,除了一个重要特征:Cj绑定到命令eval-print-last-sexp。该命令获取 point 之前的 S 表达式,对其进行计算,并将结果打印在缓冲区中。要在其他模式下 获得附加到 Cj的常用换行和缩进功能,您必须按Enter,然后按Tab。
Lisp interaction mode is identical to Emacs Lisp mode except for one important feature: C-j is bound to the command eval-print-last-sexp. This command takes the S-expression just before point, evaluates it, and prints the result in the buffer. To get the usual newline-and-indent functionality attached to C-j in other modes, you must press Enter, followed by Tab.
请记住,S 表达式是 Lisp 中任何语法上有效的表达式。因此,您可以在Lisp交互模式下使用Cj 来检查变量的值、输入函数定义、运行函数等。例如,如果您键入auto-save-interval并按 Cj,则会显示该变量的值(默认为 300)。如果您键入defun并在最后一个右括号后按Cj,Emacs 会存储定义的函数(以供将来调用)并打印其名称;在这种情况下,Cj类似于CMx(对于eval-defun),只是光标必须位于正在定义的函数之后(而不是之前或中间)。如果您调用函数,Emacs 会计算(运行)该表达式并以该函数返回的任何值进行响应。
Remember that an S-expression is any syntactically valid expression in Lisp. Therefore, you can use C-j in Lisp interaction mode to check the values of variables, enter function definitions, run functions, and so on. For example, if you type auto-save-interval and press C-j, the value of that variable (300 by default) appears. If you type a defun and press C-j after the last right parenthesis, Emacs stores the function defined (for future invocation) and prints its name; in this case, C-j is similar to C-M-x (for eval-defun) except that the cursor must be after (as opposed to before or in the middle of) the function being defined. If you invoke a function, Emacs evaluates (runs) the expression and responds with whatever value the function returns.
Lisp 交互模式中的Cj为您提供了一种极好的方式来使用、增量开发和调试 Emacs Lisp 代码,并且由于 Emacs Lisp 是“真正的”Lisp,因此它甚至对于为其他 Lisp 系统开发一些代码很有用。
C-j in Lisp interaction mode gives you an excellent way to play with, incrementally develop, and debug Emacs Lisp code, and since Emacs Lisp is "true" Lisp, it is even useful for developing some bits of code for other Lisp systems.
[ 12 ]缩进样式绑定在 Lisp 模式的 Emacs Lisp 代码中。如果您是一位经验丰富的 Lisp 黑客,您可以检查 Emacs Lisp 目录中的lisp-mode.el代码,并确定如何按照您希望的方式自定义缩进。一个好的起点是函数lisp-indent-line。
[12] The indentation style is bound up in the Emacs Lisp code for Lisp mode. If you are an experienced Lisp hacker, you can examine the code for lisp-mode.el in the Emacs Lisp directory and determine how to customize indentation the way you wish. A good place to start looking is the function lisp-indent-line.
正如您在本书中可能已经注意到的那样,Emacs 非常强大且非常灵活。您可以利用这种强大功能和灵活性来配置 Emacs,以符合您的工作风格和偏好。我们将了解几个最常见的自定义任务,并查看一些资源,以获得比我们在此提供的更深入的覆盖范围。
As you have probably noticed throughout this book, Emacs is very powerful and very flexible. You can take advantage of that power and flexibility to configure Emacs to match your work style and preferences. We'll look at several of the most common customization tasks and also look at a few resources for more in-depth coverage than we can provide here.
您可以在以下位置自定义 Emacs: 三种方式:使用Custom,交互界面;使用选项菜单,这实际上是自定义的后门;并直接添加 Lisp 行 你的.emacs文件。本章涵盖了所有这三种方法。
You can customize Emacs in three ways: using Custom, the interactive interface; using the Options menu, which is really a backdoor to Custom; and directly by adding lines of Lisp to your .emacs file. This chapter covers all three of these methods.
但无论您使用什么方法, .emacs启动文件都会被修改。当您通过该界面保存设置时,自定义会为您修改它。 “选项”菜单在后台调用“自定义”;当您选择“保存选项”时,自定义会再次修改.emacs。在整本书中,我们一直为您提供直接添加到 .emacs 的行,以便您可以根据自己的喜好调整 Emacs。
No matter what method you use, though, the .emacs startup file is modified. Custom modifies it for you when you save settings through that interface. The Options menu invokes Custom behind the scenes; when you choose Save Options, Custom again modifies .emacs. Throughout the book, we have been providing lines for you to add to .emacs directly so you could adjust Emacs to your preferences.
在开始之前,我们应该说,自定义 Emacs 最简单的方法是从“选项”菜单中选择一个选项,然后选择“保存选项”。此菜单旨在提供轻松访问更改常用选项的功能。例如,您可能不喜欢工具栏及其图标,感觉这样的图形 codswallop 低于 Emacs 用户。您可以通过“选项”菜单上的“显示/隐藏”选项隐藏工具栏。选择“保存选项”会修改 .emacs,因此每次启动 Emacs 时工具栏都会隐藏。如果有一天你错过了工具栏,你可以用同样的方式找回它。
Before we get started, we should say that the very easiest way to customize Emacs is by selecting an option from the Options menu and choosing Save Options. This menu is designed to provide easy access to changing frequently used options. For example, you may not like the Toolbar and its icons, feeling that such graphical codswallop is beneath an Emacs user. You can hide the toolbar through the Show/Hide option on the Options menu. Choosing Save Options modifies .emacs so the toolbar is hidden every time you start Emacs. And if you miss the toolbar someday, you can get it back the very same way.
在描述定制方法之后,本章继续讨论与定制相关的几个一般问题,包括如何更改字体和颜色、修改键绑定、设置 Emacs 变量、查找要加载的 Lisp 包、根据文件后缀自动启动模式以及禁止任何可能干扰您自己的.emacs 设置的全局自定义文件。
After describing customization methods, this chapter goes on to discuss several generic issues relating to customization, including how to change fonts and colors, modify your key bindings, set Emacs variables, find Lisp packages to load, start modes automatically based on file suffixes, and inhibit any global customization files that may be interfering with your own .emacs settings.
Emacs 现在附带了一个奇怪的 图形但不是图形界面,允许您自定义 Emacs 的大部分方面,而无需了解具体细节。此功能称为“自定义”,可以通过键入Mx custom或单击工具栏上的工具图标来访问。
Emacs now ships with a quirky graphical-but-not interface that allows you to customize most aspects of Emacs without knowing the gory details. This feature, known as Custom, can be accessed by typing M-x custom or by clicking the tools icon on the toolbar.
|
类型:MX 自定义 输入 Type: M-x custom Enter |
|
|
|
Emacs 显示自定义 (Mac OS X) 的启动缓冲区。 Emacs displays the startup buffer for Custom (Mac OS X). |
您可以在 给自定义屏幕的方式与您在 Emacs 任何其他部分中所做的方式非常相似。所有基本的光标移动命令(例如Cn和Cp)都可以正常工作。但这只是《Custom》故事的一部分。要完成任何有用的事情,您需要激活特殊的单词和短语。灰色框中看起来像按钮的文本片段是有问题的单词和短语。
You can move around in a given Custom screen much the way you do in any other part of Emacs. All of the basic cursor movement commands like C-n and C-p work just as they should. But that's only part of the story in Custom. To accomplish anything useful, you need to activate special words and phrases. Those bits of text in grey boxes that look like buttons are the words and phrases in question.
要激活这些按钮之一,请用鼠标单击该按钮或将光标置于其边框内,然后按Enter。图 10-1突出显示了这些选项。
To activate one of these buttons, click on the button with the mouse or position your cursor inside its borders and press Enter. Figure 10-1 highlights these options.
图 10-1。使用鼠标光标(顶部)和键盘光标(底部)激活自定义按钮 (Mac OS X)
Figure 10-1. Custom button activation using the mouse cursor (top) and the keyboard cursor (bottom) (Mac OS X)
当您看完一个屏幕后,如果您不想更改任何内容,可以键入Cx k来终止当前缓冲区并返回到上一个屏幕。您还可以激活下面讨论的通用标题集中的“完成”按钮。
When you finish looking at a screen, if you are not interested in changing anything, you can type C-x k to kill the current buffer and go back to the previous screen. You can also activate the Finish button in the common header set discussed next.
在每页的顶部 Custom中是一组常用的按钮,如图10-2所示。这些选项影响整个缓冲区。
At the top of each page in Custom is a common set of buttons shown in Figure 10-2. These options affect the entire buffer.
从这里您可以执行以下任意任务:
From here you can perform any of the following tasks:
Make immediate changes that last for the duration of this session but will be reset the next time you start Emacs.
立即进行更改,这些更改将持续到本次会话期间,并且也会在您下次启动 Emacs 时生效。这些更改存储在您的.emacs文件中。
Make immediate changes that last for the duration of this session and will also be in place the next time you start Emacs. These changes are stored in your .emacs file.
Switch back to the previous values (previous to your current changes, anyway).
切换回之前保存的值。在这种情况下,“已保存”意味着保存以供将来的会话使用。如果您尚未对变量进行(并随后保存)任何自定义,则此选项无效。
Switch back to the previously saved values. In this case, "saved" means saved for future sessions. If you haven't made (and subsequently saved) any customizations to a variable, this option has no effect.
这个选项还蛮多的 照它说的做。自定义所做的任何自定义(无论是针对本次会话还是将来的会话)都将被删除。.emacs文件中您自己的个人条目 应保持完整,但在删除任何信息之前进行备份始终是一个好主意。
This option pretty much does what it says. Any customizations made by Custom, whether for this or future sessions, are removed. Your own personal entries in your .emacs file should remain intact, but it's always a good idea to make a backup before deleting any information.
关闭此缓冲区并返回到先前的自定义缓冲区或返回到您启动自定义的缓冲区。请注意,您还可以按q键从自定义缓冲区中的任何位置激活“完成”。
Close this buffer and return to the previous customization buffer or back to the buffer from which you launched Custom. Note that you can also press the q key to activate Finish from anywhere in a Custom buffer.
当您修改页面上的多个选项并希望一次保存所有选项(并以相同的方式)时,这些选项非常有用。
These options are useful when you modify more than one option on a page and want to save them all at once (and in the same way).
自定义将选项划分到自定义组中,这些组是在父组和子组的层次结构中设置的。要转到您正在查看的组的父组,请在 : 提示后选择相关父组的按钮Go to parent
group。为了更容易找到东西,一个组可能有多个父级。例如,I18n(国际化)组有两个父项
Environment和,如图10-3Editing所示。
Custom corrals options into customization groups, which are set up in
a hierarchy of parent and child groups. To go to the parent group for
the group you're looking at, choose the button for
the parent group in question following the Go to parent
group: prompt. To make it easier to find things, a group
might have more than one parent. For example, the I18n
(internationalization) group has two parents,
Environment and Editing, as
shown in Figure 10-3.
选择Go to parent group与选择“完成”非常相似,但不关闭缓冲区。如果您只是四处寻找相关变量,那么这是一个有用的选项。我们将在本章后面向您展示更好的方法来查找要自定义的特定功能。
Choosing Go to parent group is much like choosing
Finish but without closing the buffer. It's a useful
option if you're just poking around looking for
related variables. We'll show you better ways to
find particular features to customize later in this chapter.
了解方法后,您就可以解决自定义 Emacs 的问题了。自定义的每个屏幕都会列出变量和其他设置。您可以在变量名称右侧的灰色文本字段中编辑任何变量的值。应列出当前值。只需删除当前值并输入新值即可。
After you learn your way around, you can tackle customizing Emacs. Each screen of Custom lists variables and other settings. You can edit the value of any variable in the grey text field to the right of variable's name. The current value should be listed. Just delete the current value and type the new value.
然而,更改值并不是您必须采取的最后一步。您需要保存更改才能生效。您可以使用“状态”按钮保存更改(如前所述,要以相同的方式保存页面上的所有值,您可以使用屏幕顶部附近的选项)。与“自定义”的其他部分一样,您可以使用鼠标或键盘。在 State 上单击鼠标左键应该会弹出如图 10-4所示的列表。根据变量和您所做的更改(如果有),您可能拥有也可能不拥有所有可用选项。
Changing a value, however, is not the last step you have to take. You need to save the change before it will take effect. You use the State button to save the change (as mentioned earlier, to save all the values on a page in the same way, you can use the options near the top of the screen). As with other parts of Custom, you can use your mouse or the keyboard. Clicking the left mouse button on State should bring up the list shown in Figure 10-4. Depending on the variable and the change you made (if any), you may or may not have all of the options available.
当然你也可以激活 将光标放在状态按钮上并按Enter。这应该创建第二个窗口,其选项与使用鼠标时获得的选项相同。图 10-5显示了使用Enter键选择 State 时看到的选项。此列表是动态的,仅显示您可用的选项。 (如果您尚未更改任何内容,它不会显示任何选项,但会发出错误提示音。)
Of course, you can also activate the State button by placing your cursor on it and pressing Enter. That should create a second window with effectively the same options you get when using the mouse. Figure 10-5 shows the options you see using the Enter key to select State. This list is dynamic, showing only options that are available to you. (It won't show any options if you haven't changed anything yet, but it beeps with an error.)
使用鼠标时,只需从列表中选择所需的选项即可。使用文本方法时,请键入与您所需的选择相对应的数字(或其他字符)。可用的选项与应用于整个缓冲区的选项类似。您将看到熟悉的保存和重置选项以及一些新选项:
When using the mouse, simply select the desired choice from the list. When using the text approach, type the number (or other character) corresponding to your desired choice. The options available are similar to those that apply to the entire buffer. You'll see the familiar save and reset options along with a few new ones:
Same as the global option. Saves the new value for the duration of this session.
与全局选项相同。立即应用此值并更新您的.emacs文件,以便每次启动 Emacs 时都会使用新值。
Same as the global option. Applies this value immediately and updates your .emacs file so the new value is used whenever you start Emacs.
返回到变量的当前值。任何未保存的更改都会被丢弃,但保存的更改(即使只是针对此会话)也算作“当前”更改。
Goes back to the current value for the variable. Any unsaved changes are thrown out, but changes saved—even just for this session—count as "current" changes.
与全局选项相同。对变量的任何更改都会被删除,并且.emacs会根据需要进行更新。
Same as the global option. Any changes to the variable are removed and .emacs is updated if needed.
返回到设置“当前”值之前保存的值。换句话说,恢复为最近保存所替换的值。
Goes back to the value saved before the "current" value was set. In other words, revert to the value replaced by the most recent save.
您可以添加自己的评论 到变量以帮助您记住进行此更改的原因。评论的有效期与保存的更改一样长。仅对当前会话进行的更改仅保留当前会话的注释(通常不有用)。添加到您为未来会话保存的更改的注释将在这些未来会话中显示在此屏幕上。删除自定义值也会删除注释。
You can add your own comments to the variable to help you remember why you made this change. Comments last as long as the saved change. Changes made only for the current session keep the comment only for the current session (not often useful). Comments added to changes that you save for future sessions show up on this screen in those future sessions. Erasing the customized value also erases comments.
如果您犯了错误或提供了不适合该变量的值,您会在迷你缓冲区中收到一条简短的错误消息。与 Unix 世界中成长的其他实用程序一样,没有消息就是好消息。如果您没有看到任何错误消息,则表明您的更改已成功保存。
If you make a mistake or supply a value that is not appropriate for the variable, you get a brief error message in the minibuffer. As with other utilities that grew up in the world of Unix, no news is good news. If you don't see any error messages, your change was successfully saved.
单词缩写模式 是即时纠正拼写错误的好方法。但除非它被打开,否则它不能以这种方式工作。让我们使用 Custom 来打开单词缩写模式(在第 3 章中讨论)。
Word abbreviation mode is a wonderful way to correct typos on the fly. But it can't work that way unless it is turned on. Let's use Custom to turn on word abbreviation mode (discussed in Chapter 3).
|
单击缩写组旁边的转至组按钮 Click on the Go to Group button next to Abbreviations group |
|
|
|
缩写组。 The Abbreviations group. |
|
单击“缩写模式”组旁边的“转到组”按钮 Click on the Go to Group button next to Abbrev Mode group |
|
|
|
缩写模式组。 The Abbrev Mode group. |
最后,我们进入了可以设置选项的屏幕!请注意,第一个内容行“缩写模式组”位于“状态”按钮 旁边visible group members are all at
standard settings。另请注意屏幕底部附近的缩写模式显示this option is unchanged from its
standard setting。
Finally, we're at a screen where we can set the
option! Notice that the first content line, Abbrev Mode group, says
next to the State button visible group members are all at
standard settings. Also note that Abbrev Mode, near the
bottom of the screen, says this option is unchanged from its
standard setting.
我们将通过按“切换”按钮打开“缩写模式”选项。
We'll turn on the Abbrev Mode option by pressing the Toggle button.
缩写模式组附近的文本现在显示:You have edited
something in this group, but not set it。 “缩写模式”选项附近的文本显示:“哟” u have edited the value as text,
but you have not set the option。这些都清楚地暗示我们必须再采取一步来设置此选项。如果这些提示还不够,迷你缓冲区会明确指示,To install your edits, invoke [State] and choose
the Set operation.我们可以单击该选项旁边的“状态”按钮,但单击屏幕顶部附近的“保存以供将来的会话”选项也同样方便(如果不是更方便的话)。这会将我们更改的所有选项保存在缓冲区中,在我们的例子中这只是一个选项。
The text near Abbrev Mode group now says, You have edited
something in this group, but not set it. The text near the
Abbrev Mode option says, you have edited the value as text,
but you have not set the option. These are clear hints that
we must take one more step to set this option. And if those
weren't hints enough, the minibuffer explicitly
instructs, To install your edits, invoke [State] and choose
the Set operation. We could click on the State button next
to the option, but it's just as convenient (if not
more convenient) to click on the Save For Future Sessions option near
the top of the screen. This saves all options we've
changed in the buffer, which in our case is just one option.
|
在屏幕顶部附近,单击“保存以供将来使用” Near the top of the screen, click on Save for Future Sessions |
|
|
|
Emacs 告诉您它编写了.emacs文件。 Emacs tells you that it wrote the .emacs file. |
在“缩写模式”组旁边,现在显示“.” something in this
group has been set and saved。在“缩写模式”选项旁边,写着:this option has been set and
saved。另请注意,Abbrev现在出现在模式行上;我们确实成功开启了单词缩写模式。重复单击“完成”以终止所有自定义缓冲区。
Next to the Abbrev Mode group it now says, something in this
group has been set and saved. Next to the Abbrev Mode
option it says, this option has been set and
saved. Note also that Abbrev appears on
the mode line now; we have indeed successfully turned on word
abbreviation mode. Click Finish repeatedly to kill all the Custom
buffers.
恭喜;您即将开始自定义 Emacs。您应该花一些时间在自定义提供的各个组中闲逛,以了解您可以控制的内容。我们将在后面的部分中讨论自定义字体、颜色和键盘映射的热门主题。但定制提供了更广泛的调整领域。不要害怕环顾四周。您始终可以使用“重置”选项来撤消某些与您的行为方式不同的操作 期望或想要的。
Congratulations; you're on your way to customizing Emacs. You should spend some time wandering around in the various groups Custom offers to get a sense of the things you can control. We'll look at the popular topics of customizing fonts, colors, and keyboard mappings in later sections. But Custom offers a much wider variety of areas to tweak. Don't be afraid to look around. You can always use the Reset option to undo something that doesn't behave the way you expected or wanted.
您还可以通过 有点后门:选项菜单。图 10-6显示了“选项”菜单。此顶层有三个关键条目:
You can also access Custom through a bit of a back door: the Options menu. Figure 10-6 shows the Options menu. There are three key entries at this top level:
Allows you to turn on (and off) several features of Emacs including the menu bar and toolbar.
A quick shortcut to saving any changes you make to Emacs through the Options menu.
子菜单允许您调整字体和变量等常用项目,并帮助您浏览和搜索自定义可用的选项。
A submenu that allows you to tweak common items such as fonts and variables as well as helping you browse and search through the options available to Custom.
让我们来处理另一个自定义示例 在选项菜单的帮助下。 Dired(第 5 章中讨论)有许多可定制的功能。其中一项功能是dired-view-command-alist变量。这是帮助程序应用程序的列表,可让您打开各种类型的文件。此功能对于查看图像或 PDF 文件等二进制文件非常方便。此帮助应用程序列表是针对 Linux 定制的。如果您想使用其他应用程序或者您使用的是 Windows 或 Mac 系统,则需要自定义此变量。
Let's tackle another Custom example with the help of the Options menu. Dired (discussed in Chapter 5) has many customizable features. One such feature is the dired-view-command-alist variable. This is a list of helper applications that allow you to open various kinds of files. This feature can be quite handy for viewing binary files such as images or PDF files. This list of helper applications is tailored to Linux. If you want to use other applications or you're on a Windows or Mac system, you'll need to customize this variable.
在自定义此选项之前,您需要打开一个目录或只需键入Cx d即可输入 Dired。接下来,从“选项” → “自定义 Emacs”菜单中,选择“特定选项”项。
Before you customize this option, you need to open a directory or simply type C-x d to enter Dired. Next, from the Options → Customize Emacs menu, select the Specific Option item.
|
选择选项→自定义 Emacs →特定选项 Choose Options→ Customize Emacs→ Specific Option |
|
|
|
迷你缓冲区会提示输入特定的选项来自定义 (Windows)。 The minibuffer prompts for a specific option to customize (Windows). |
迷你缓冲区会提示输入选项名称。我们想要自定义 dired-view-command-alist。
The minibuffer prompts for an option name. We want to customize dired-view-command-alist.
|
类型:dired-view-command-alist Enter Type: dired-view-command-alist Enter |
|
|
|
在自定义 (Windows) 中编辑列表条目。 Editing a list entry in Custom (Windows). |
您应该看到熟悉的用于保存和重置值的自定义选项以及dired-view-command-alist变量的值。对于这个特定的变量,我们有一个常见文件类型的条目列表,包括 PostScript 文件、PDF 文档和图像。要更改现有条目之一,只需移至该String
行并编辑灰色文本即可启动您想要使用的应用程序。 (您还可以通过编辑该行中的文本来更改文件名模式Regexp。)例如,可以使用 Mac OS X 中的打开命令查看 PDF 文档,因此我们可以更改该行,如图10-7所示。事实上,在 Mac OS X 上,您可以对几乎所有类型的文件使用通用打开命令。在 Windows 上,这甚至更容易。只需输入
%s作为字符串,Windows 就会使用其默认应用程序打开该文件类型。
You should see the familiar Custom options for saving and resetting
the values along with the value of the dired-view-command-alist variable. For this
particular variable, we have a list of entries for common file types
including PostScript files, PDF documents, and images. To alter one
of the existing entries, simply move to the String
line and edit the text in grey to launch the application you would
like to use. (You can also alter the filename pattern by editing the
text in the Regexp line.) For example, PDF
documents can be viewed with the open command in Mac OS X, so we
could change that line as shown in Figure 10-7. In
fact, on Mac OS X, you can use the generic open command for just
about every type of file. On Windows it is even easier. Simply enter
%s as the string, and Windows uses
its default application to open that file type.
如果您不使用 DVI 文档,则可以使用图 10-8中所示的 DEL 按钮删除该关联。
If you don't use DVI documents, you can get rid of that association using the DEL button shown in Figure 10-8.
您还可以通过单击任何 INS 按钮来添加新的文档类型和查看器。 (关联的顺序对于该特定变量并不重要,但对于其他列表可能很重要。)要 在 PDF 条目之前插入新关联,请激活 PDF 条目左侧的 INS 按钮。
You can also add new document types and viewers by clicking on any of the INS buttons. (The order of the associations isn't important for this particular variable, but it might matter for other lists.) To insert a new association before the PDF entry, activate the INS button to the left of the PDF entry.
|
单击 PDF 条目左侧的 INS。 Click on INS to the left of the PDF entry. |
|
|
|
将新项目添加到自定义 (Windows) 列表中的第一步。 The first step in adding a new item to a list in Custom (Windows). |
Regexp现在,您可以通过编辑和
行来添加在 PC 上播放 MP3 文件的关联String。请注意,您必须提供与您的系统匹配的帮助应用程序(本例中为 winamp)的路径。如前所述,如果 winamp 已经是 MP3 的默认帮助程序应用程序,您可以简单地键入%s而不是
Stringwinamp 的完整路径。
Now you can add an association for playing MP3 files on a PC by
editing both the Regexp and
String lines. Note that you'd
have to supply a path to your helper application (winamp in this
example) that matched your system. As mentioned earlier, if winamp
was already the default helper application for MP3s, you could simply
type %s for the
String instead of the complete path to winamp.
|
键入[.]mp3\ ' 并键入
Type [.]mp3\' for the
|
|
|
|
第二步添加新项目(Windows)。 The second step in adding a new item (Windows). |
您可能已经注意到“选项”菜单中的“保存更改”选项。此菜单项保存您通过“选项”菜单所做的更改。例如,您可以修改诸如工具栏是否可见或“会话之间文件中的保存位置”选项等设置。它不会保存您通过“自定义”所做的更改 - 即使您从“选项” → “自定义 Emacs”子菜单项之一启动“自定义”。您仍然需要使用常规的自定义选项来保存这些更改。
You may have noticed the Save Changes option in the Options menu. This menu item saves changes you make through the Options menu. For example, you can modify such settings as whether or not the toolbar is visible or the Save Place in Files between Sessions option. It does not save changes you have made through Custom—even if you launched Custom from one of the Options → Customize Emacs submenu items. You'll still need to use the normal Custom options to save those changes.
对于我们的 Dired 变量示例,您需要选择可用的“保存”选项之一。在这种情况下,我们将仅为当前会话保存它。
For our Dired variable example, then, you'll need to select one of the Save options available. In this case, we'll save it for the current session only.
|
单击设置当前会话 Click on Set for Current Session |
|
|
|
仅保存此会话的更改 (Windows)。 Saving changes for this session only (Windows). |
保存更改后,您可以照常退出缓冲区,方法是单击“完成”按钮,键入q或键入Cx k来终止缓冲区。
When you're done saving your changes, you can exit the buffer as usual by clicking the Finish button, typing q, or typing C-x k to kill the buffer.
最大的障碍之一 使用自定义可以知道特定变量的位置。自定义有很多组和子组,而且它们并不总是直观的。有两种快速方法可以“搜索”特定变量。您可以按Tab 键使用迷你缓冲区中的完成功能,也可以浏览整个自定义层次结构。
One of the biggest stumbling blocks to using Custom is knowing where a particular variable is located. Custom has a lot of groups and subgroups—and they aren't always intuitive. There are two quick ways to "search" for a specific variable. You can press Tab to use the completion feature in the minibuffer or you can browse through the entire Custom hierarchy.
使用完成
方法,输入Mxcustomize-option或选择选项→自定义 Emacs →特定选项。你会Customize Option在迷你缓冲区中看到: 。您可以输入类似字体的字符串
,然后按Tab键查看哪些变量以该字符串开头。
To use the completion
approach, type M-x customize-option or select
Options→ Customize Emacs→ Specific Option.
You'll see Customize Option: in
the minibuffer. You can type a string like font
and then hit the Tab key to see what
variables start with that string.
您还可以使用Mxcustomize-apropos(或选项→自定义 Emacs →选项匹配正则表达式)创建一个带有与正则表达式匹配的选项的自定义缓冲区。您可以输入正则表达式(或简单的字符串),自定义会构建一个新的缓冲区,其中包含包含匹配选项的所有组。
You can also create a custom buffer with options matching a regular expression with M-x customize-apropos (or Options→ Customize Emacs→ Options Matching Regexp). You can type in a regular expression (or a simple string) and Custom builds a new buffer with all groups containing matching options.
如果您想浏览层次结构以在相当紧凑的视图中查看相关的变量组,请选择选项→ 自定义 Emacs →浏览自定义组。您应该会看到类似于图 10-9 的屏幕。
If you want to browse the hierarchy to see the related groups of variables in a reasonably compact view, select Options → Customize Emacs → Browse Customization Groups. That should land you on a screen similar to Figure 10-9.
您可以像激活其他自定义按钮一样激活 [+] 和 [-] 按钮(用鼠标单击它们或将键盘光标移动到它们并按Enter 键。)这使您可以浏览整个自定义组集并亚组。找到要查找的变量后,单击该变量旁边的“选项”按钮,或者如果要编辑组中的多个变量,请单击该变量父组的“组”按钮。
You can activate the [+] and [-] buttons just like you do other Custom buttons (click on them with your mouse or move the keyboard cursor to them and press Enter.) This allows you to browse the entire set of Custom groups and subgroups. After you find the variable you're looking for, click on the Option button next to the variable or click on the Group button for the variable's parent group if you want to edit multiple variables in the group.
几乎可以用您能想到的任何方式自定义 Emacs。几乎您在屏幕上看到的所有内容、每个命令、击键、消息等都可以更改。正如您可能想象的那样,大多数自定义都涉及 Emacs 启动文件 .emacs。
It's possible to customize Emacs in just about any way you can imagine. Almost everything you see on the screen, every command, keystroke, message, and so on, can be changed. As you may imagine, most customizations involve the Emacs startup file .emacs.
上一节 讨论了交互式定制工具“自定义”,但省略了有关“为将来的会话保存”时发生的情况的一些详细信息。 Custom 将配置信息放置在您的.emacs文件中。有些事情根本无法通过自定义来完成(目前)。一旦熟悉了 .emacs文件中的语句类型,您可能还会发现直接添加一两行会更容易。
The previous section discussed the interactive customization tool, Custom, but left out some of the details on what happens any time you "save for future sessions." Custom places the configuration information in your .emacs file. Some things simply cannot be done through Custom (yet). Once you get familiar with the types of statements that go into your .emacs file, you may also just find it easier to add a line or two directly.
我们应该强调,使用自定义或手动编辑 .emacs不是一个非此即彼的命题。当您通过“自定义”保存选项时,它会将其设置添加到.emacs文件的末尾,并警告您不要手动编辑它们。尽管有此禁止,您仍然可以轻松地将自己的自定义添加到该文件的开头。为了说明这一点, 示例 10-1显示了 Mac OS X 的示例 .emacs文件,其中显示了用户直接进行的编辑以及自定义添加的部分(以粗体显示)
We should emphasize that using Custom or editing .emacs by hand is not an either-or proposition. When you save options via Custom, it adds its settings to the end of your .emacs file and warns you not to edit them by hand. Despite this prohibition, you can easily add your own customizations to the beginning of that file. To illustrate this, Example 10-1 shows a sample .emacs file for Mac OS X that shows edits made directly by the user as well as sections added by Custom (shown in bold)
例10-1。 Mac OS X 的 .emacs 文件,其中包含由用户和自定义添加的行
Example 10-1. A .emacs file for Mac OS X with lines added by the user and by Custom
(setq mac-command-key-is-meta nil)
(日记)
(setq 加载路径 (cons "~/elisp" 加载路径))
(自动加载'html-helper-mode“html-helper-mode”“Yay HTML”t)
(setq html-helper-build-new-buffer t)
(setq 自动模式列表 (cons '("\.html$" . html-helper-mode) 自动模式列表))
(setq-默认缩进制表符模式为零)
(setq-默认制表符宽度 15)
(setq-默认缩写模式 t)
(读取缩写文件“~/.abbrev_defs”)
(setq 保存缩写 t)
(fset '粗体字
[?\C- 转义 ?f ?\Cx ?\Cx ?< ?b ?> ?\Cx ?\Cx ?< ?/ ?b ?>])
(fset 'italword
[?\C- 转义 ?f ?\Cx ?\Cx ?< ?e ?m 退格 退格 ?i ?>
?\Cx ?\Cx ?< ?/ ?i ?>])
(全局设置键“\Cx\C-kI”'italword)
(setq shell-文件名“/bin/zsh”)
(添加钩子'comint-output-filter-functions
'comint-watch-password-prompt)
(自定义设置变量
;;自定义设置变量是由自定义添加的。
;;如果您手动编辑它,可能会弄乱它,所以要小心。
;;您的 init 文件应该只包含一个这样的实例。
;;如果有多个,它们将无法正常工作。
'(全局字体锁定模式 t nil(字体核心))
'(文本模式挂钩(引用(打开自动填充文本模式挂钩识别))))
(自定义设置面孔
;;自定义设置面是由自定义添加的。
;;如果您手动编辑它,可能会弄乱它,所以要小心。
;;您的 init 文件应该只包含一个这样的实例。
;;如果有多个,它们将无法正常工作。
)(setq mac-command-key-is-meta nil)
(diary)
(setq load-path (cons "~/elisp" load-path))
(autoload 'html-helper-mode "html-helper-mode" "Yay HTML" t)
(setq html-helper-build-new-buffer t)
(setq auto-mode-alist (cons '("\.html$" . html-helper-mode) auto-mode-alist))
(setq-default indent-tabs-mode nil)
(setq-default tab-width 15)
(setq-default abbrev-mode t)
(read-abbrev-file "~/.abbrev_defs")
(setq save-abbrevs t)
(fset 'boldword
[?\C- escape ?f ?\C-x ?\C-x ?< ?b ?> ?\C-x ?\C-x ?< ?/ ?b ?>])
(fset 'italword
[?\C- escape ?f ?\C-x ?\C-x ?< ?e ?m backspace backspace ?i ?>
?\C-x ?\C-x ?< ?/ ?i ?>])
(global-set-key "\C-x\C-kI" 'italword)
(setq shell-file-name "/bin/zsh")
(add-hook 'comint-output-filter-functions
'comint-watch-for-password-prompt)
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(global-font-lock-mode t nil (font-core))
'(text-mode-hook (quote (turn-on-auto-fill text-mode-hook-identify))))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
)刚开始时,您可能会在找到合适的.emacs文件时遇到一些困难 。 Emacs 实际上会查找各种启动文件。按顺序排列,它们是:
You might have a bit of trouble finding the right .emacs file to work with when you're first starting out. Emacs actually looks for a variety of startup files. In order, they are:
字节编译的 Lisp 版本或您的启动文件。这是不可编辑的,但如果您有一个大而复杂的启动文件,可以使启动更快。
The byte-compiled Lisp version or your startup file. This is not editable, but can make startup quicker if you have a big, complex startup file.
启动文件的更正式名称。您可以使用 Lisp 命令来自定义和初始化整个 Emacs 环境。
The more formal name for your startup file. You can use Lisp commands to customize and initialize your entire Emacs environment.
启动文件的通用名称。与.emacs.el文件完全相同 ,只是没有 .el扩展名。两者都是可编辑的。
The common name for the startup file. Exactly like the .emacs.el file, just without the .el extension. Both are editable.
一旦 Emacs 找到其中一个文件,就完成了;然后就进入启动的下一步。您不能为大型自定义设置一个.emacs.elc ,然后 为最后几个自定义设置一个单独的.emacs 。对不起!
As soon as Emacs finds one of these files, that's it; then it's on to the next step in startup. You can't have a .emacs.elc for the big customizations and then a separate .emacs for the last few. Sorry!
对于所有使用基于 Microsoft Windows 的系统的 Emacs 用户,您可能会遇到此文件的变体,它以下划线 ( _ ) 而不是点 (. ) 开头。过去,Windows 文件系统在第一个点之前需要一些内容,因此 .emacs是无效的文件名。因此, _emacs被采用。有关.elc和.el变体的相同顺序和注释也 适用。在现代版本的 Windows 中, .emacs是有效的文件名,点变体优先于下划线版本。
For all you Emacs users on Microsoft Windows-based systems, you might bump into a variation of this file that begins with an underscore ( _ ) rather than a dot (. ). In the past, the Windows filesystem required something before the first dot, so .emacs was an invalid filename. Consequently, _emacs was adopted. The same order and notes about the .elc and .el variants applies. In modern versions of Windows, .emacs is a valid filename and the dot variations take precedence over the underscore versions.
某些更改需要 Emacs Lisp 编程知识(参见第 11 章);其他人即使没有这些知识也很简单。在本章中,我们将介绍各种不需要编程知识的有用自定义。然而,现在您需要知道这一点:每个 Emacs 命令对应于 Lisp 函数,其形式为:
Some changes require a knowledge of Emacs Lisp programming (see Chapter 11); others are simple enough without such knowledge. In this chapter, we cover a variety of useful customizations that require no programming knowledge. For now, however, you need to know this: every Emacs command corresponds to a Lisp function, which has the form:
( )function-name arguments
(function-name arguments
)例如,如果要将光标向前移动一个单词,请键入Mf。你实际上正在做的是运行 Lisp 函数:
For example, if you want to move the cursor forward by a word, you type M-f. What you are actually doing is running the Lisp function:
(前向字1)
(forward-word 1)
关于.emacs文件的两个重要注释是有序的。首先,如果您将代码插入到 .emacs文件中,您最终可能会插入一些导致 Emacs 失败或行为异常的内容。如果发生这种情况,您可以在不运行.emacs 文件的情况下调用 Emacs:只需使用命令行选项-q调用 Emacs ,Emacs 将不会运行您的 .emacs文件。 (第 13 章 提供了在 Windows 和 Mac OS X 上从命令行启动 Emacs 的说明。)然后您可以检查该文件以找出问题所在。
Two important comments concerning .emacs files are in order. First, if you are inserting code into your .emacs file, you may end up putting in something that causes Emacs to fail or behave strangely. If this happens, you can invoke Emacs without running your .emacs file: simply invoke Emacs with the command-line option -q, and Emacs will not run your .emacs file. (Chapter 13 gives instructions for starting Emacs from the command-line on Windows and Mac OS X.) You can then examine the file to figure out what went wrong.
另一条评论也许是我们可以为您提供的关于自定义 Emacs 环境的最重要的建议: 无情地从其他用户那里窃取。特别是,如果您正在处理涉及配置问题或有关某些专用模式的微妙问题的混乱情况,则其他用户可能已经解决了该问题。这绝不是不诚实或颠覆性的;相反,它是受到 GNU Emacs 开发者的鼓励,他们宁愿软件被共享也不愿保留给自己。 Emacs 甚至提供了一种简单的方法来尝试其他用户的 .emacs文件:使用选项 -u username调用 Emacs ,然后username的 .emacs文件将代替您的运行。 (当然,这仅适用于多用户系统上的用户。)
The other comment is perhaps the most important piece of advice we can give you concerning customizing your Emacs environment: steal mercilessly from other users. In particular, if you are dealing with a messy situation involving a configuration problem or a subtle point about some specialized mode, it is possible that some other user has solved the problem(s) already. This is not dishonest or subversive in any way; rather, it is encouraged by the makers of GNU Emacs, who would rather software be shared than kept to oneself. Emacs even provides an easy way to try out other users' .emacs files: invoke Emacs with the option -u username, and username's .emacs file will run instead of yours. (Of course, this works only with users on multiuser systems.)
事实上,Web 上有许多示例.emacs文件。 (查看“非常非官方的” .emacs网站, http://www.dotemacs.de/。)
In fact, numerous example .emacs files are available on the Web. (Check out "the very unofficial" .emacs site, http://www.dotemacs.de/.)
这是一个(非常)简单的.emacs文件的快速示例 :
Here's a quick example of a (very) simple .emacs file:
;;打开字体锁定模式以在某些模式下为文本着色 (全局字体锁定模式 t) ;;确保缩进代码时使用空格 (setq-默认缩进制表符模式为零)
;; Turn on font-lock mode to color text in certain modes (global-font-lock-mode t) ;; Make sure spaces are used when indenting code (setq-default indent-tabs-mode nil)
以 2 开头的行 分号是注释。它们旨在帮助您了解正在配置的内容。有时它们还会列出可能的值或先前的值。您可以在评论中说出任何您想说的内容,只要它适合一行即可。如果需要溢出到第二行或第三行,只需以 ;; 开始每个连续行。
The lines beginning with two semicolons are comments. They're meant to help you understand what is being configured. Sometimes they also list possible values or the previous value. You can say anything you want in a comment—as long as it fits on one line. If you need to spill over onto a second or third line, just begin each successive line with ;;.
空行将被忽略。每隔一行(不是空白或注释)都被视为 Lisp 程序的一部分,执行该程序是为了配置 Emacs 会话。在此示例中,我们首先使用 参数t (true 或“on”)调用global-font-lock-mode函数。接下来,我们确保在编写代码时使用Tab键实际上不会插入制表符,而是使用空格。 (在编写代码时这是一件好事,否则在使用不同制表符宽度的系统上,您的代码可能会变得非常混乱。)我们使用setq-default函数将indent-tabs-mode指定为nil( false 或“关闭”)值。使用setq-default的优点是仅设置默认值 - 选择覆盖此值的模式仍然可以这样做。
Blank lines are ignored. Every other line (that's not blank or a comment) is considered part of a Lisp program that is executed to configure your Emacs session. In this example, we first call the global-font-lock-mode function with an argument of t (true, or "on"). Next we make sure that using the Tab key when writing code doesn't actually insert a tab character but uses spaces instead. (This is a good thing to do when writing code—otherwise your code can come out very messy on systems that use a different tab width.) We use the setq-default function to assign the indent-tabs-mode a nil (false or "off") value. Using setq-default has the advantage of setting the default value only—modes that choose to override this value may still do so.
如果您是一位经验丰富的 Lisp 程序员,您可以做任何您通常可以在 Lisp 中进行的操作。当然,您需要了解一些特定的函数和变量才能有效,但这只是一个 Lisp 程序。
If you're a seasoned Lisp programmer, you can do anything you would normally have access to in Lisp. There are certainly particular functions and variables you need to know about to be effective, but it is just a Lisp program.
对于我们其他人来说,这个文件主要由在互联网或同事计算机上找到的 Lisp 块组成。您编辑您的个人价值观并希望一切顺利。真的。如果您使用 Custom 来管理所有配置更改,您甚至不必查看 .emacs,除非您想在文件开头添加自己的行或查看 Custom 所做的操作。
For the rest of us, this file mostly consists of blocks of Lisp found on the Internet or on a colleague's computer. You edit in your personal values and hope it all works. Really. If you use Custom to manage all of your configuration changes, you don't even have to look at .emacs unless you want to add your own lines at the beginning of the file or look at what Custom has done.
伟大的事情是 配置文本编辑器的特点是您可以使用编辑器本身进行更改。您可以 像访问任何其他文件一样访问.emacs文件。唯一需要注意的是你在哪里。有些人将此文件的备份副本放在奇怪的地方。您想要编辑来自主目录的文件。如果您不确定自己在哪里,可以使用全名 ~/.emacs,Emacs 会将其转换为正确的目录。
The great thing about configuring a text editor is that you can use the editor itself to make the changes. You can visit the .emacs file just as you would any other file. The only thing to watch out for is where you are. Some folks put backup copies of this file in strange places. You want to edit the file that came from your home directory. If you're unsure of where you are, you can use the full name ~/.emacs which Emacs translates to the proper directory.
另请注意,.emacs不是必需的。如果您没有任何理由定制 Emacs,它可能不存在。但是,当您准备好开始定制环境时,您应该可以随意创建它。 (通过自定义进行第一次更改也会创建 .emacs(如果不存在)。)
Note also that .emacs is not required. If you haven't had any reason to customize Emacs, it might not exist. But you should feel free to create it when you're ready to start tailoring your environment. (Making your first change via Custom will also create .emacs if it doesn't exist.)
处理该文件的最佳方法实际上是找到一个示例文件并对它进行一些小的更改。使用那些;;随意评论。如果您要更改 .emacs文件中的一行,请先复制它:
The best way to deal with this file really is to find an example file and make small changes to it. Use those ;; comments liberally. If you're going to change a line in your .emacs file, make a copy of it first:
;;关闭字体锁定 ;;(全局字体锁定模式 t) (全局字体锁定模式零)
;; Turn off font-lock ;;(global-font-lock-mode t) (global-font-lock-mode nil)
这样您就可以轻松返回 .emacs文件的已知工作版本。如果事情真的变得很糟糕,那就重新开始。重命名当前的.emacs文件,然后一次复制并粘贴其中的一小部分。
That way you can easily get back to a known, working version of your .emacs file. If things get really bad, just start over. Rename your current .emacs file and then copy and paste small chunks of it at a time.
对于模块和其他包所需的更改,这些模块的文档通常包括用于插入到.emacs中的示例行。例如,JDEE 站点包含一个示例.emacs文件,可以按原样使用或附加到现有文件。 (如果您想变得更奇特,您可以将 JDEE 示例保留在单独的文件中,并简单地包含 来自 .emacs文件的加载文件调用。有关加载文件的更多信息可以在 Elisp 文档中找到。)
For changes required by modules and other packages, the documentation for those modules usually includes example lines for insertion into your .emacs. For example, the JDEE site includes a sample .emacs file that can be used as-is or appended to an existing file. (And if you want to get fancy, you can leave the JDEE sample in a separate file and simply include a load-file call from your .emacs file. More on load-file can be found in the Elisp documentation.)
您保存 您的 .emacs就像您通常保存任何文件一样。不过,要测试您所做的任何更改,您必须执行以下两件事之一。可靠的方法是退出 Emacs 并再次启动它。如果一切都按照您的预期进行,那么您就可以开始了。
You save your .emacs just as you normally save any file. To test any changes you've made, though, you'll have to do one of two things. The sure-fire method is to quit Emacs and launch it again. If everything comes up the way you expected, you're good to go.
您还可以运行Mx load-file。系统将提示您输入文件名。只需输入~/.emacs Enter即可检查您的更改。
You can also run M-x load-file. You'll be prompted for the name of the file. Just type in ~/.emacs Enter and you should be able to check your changes.
这里要小心:当前会话中的某些内容完全有可能与新的 .emacs文件进行交互。例如,如果您已经为变量设置了默认值,则注释掉 .emacs文件的该行不会删除该值,除非您也手动删除默认值。不过,如果您的配置相当简单,那么应该没问题。重新加载 .emacs肯定比重新启动 Emacs 更快!
Be careful here: it's entirely possible that something in your current session will interact with your new .emacs file. For example, if you have already set a default value for a variable, commenting out that line of your .emacs file will not remove the value unless you also remove the default value by hand. If you've got a fairly simple configuration, though, you should be fine. Reloading .emacs is certainly faster that restarting Emacs!
无论哪种方式,一旦您验证您的配置按照您想要的方式工作,您就可以忘记这个文件。当然,直到您想要做出更多改变为止!
Either way, once you have verified that your configuration works the way you want, you can forget about this file. Until you want to make more changes, of course!
某些平台(Windows、Mac OS X 和 Unix)上的 Emacs 可以以多种固定宽度字体显示文本。它还不能很好地处理比例间距字体,尽管未来的版本预计会解决这个问题。 Emacs 可以根据系统支持的多种前景色和背景色组合来显示文本。我们将查看您更改字体的选项。您可以在任何缓冲区中进行快速、交互式的更改。您还可以自定义自动突出显示功能(例如 Isearch 和字体锁定模式)使用的字体和颜色。
Emacs on certain platforms (Windows, Mac OS X, and Unix) can display text in multiple fixed-width fonts. It doesn't yet handle proportional-spacing fonts well, although future releases are expected to address that issue. Emacs can display text in as many combinations of foreground and background colors as your system supports. We'll take a look at your options for changing fonts. You can make quick, interactive changes in any buffer. You can also customize the fonts and colors used by automatic highlight features such as Isearch and font-lock mode.
如果您想使用 Emacs 编辑基本的样式文本文档,我们还将了解如何保存和加载具有丰富字体和颜色的文本的文件。
And just in case you want to use Emacs to edit rudimentary styled-text documents, we'll also look at how to save and load files that have font and color enriched text.
自定义和编辑菜单 Emacs 为您提供了一种通过从“文本属性”菜单中选择新字体和颜色来更改当前字体和颜色的方法。
Both Custom and the Edit menu in Emacs provide you with a way to change the current font and color by picking a new one from the Text Properties menu.
要了解文本属性菜单,你会发现了解 Emacs 的内部思考很有用 就面子而言。面孔是字体和颜色的组合。 “文本属性”菜单向您提供一小组预混合的面孔以及按名称指定其他面孔的选项。
To understand the Text Properties menu, you'll find it useful to know that Emacs thinks internally in terms of faces. A face is a font and color combination. The Text Properties menu presents you with a small set of premixed faces and the option to specify others by name.
我们将在本章后面详细介绍面孔、如何命名它们以及相关的 Lisp 编程结构。现在,简单地考虑一下缓冲区中的每个角色可能都有一张不可见的与之关联的不同面孔(尽管在实践中,如果面孔变化如此频繁,那将是非常令人惊讶的!)。
We'll go into more detail about faces, how to name them, and the related Lisp programming constructs later in this chapter. For now, consider simply that every character in a buffer may have a different face invisibly associated with it (though in practice it would be quite surprising if face changes were that frequent!).
按住Shift键的同时单击鼠标左键可打开字体菜单。选择其中之一会立即更改当前框架的 Emacs 字体并重新显示该框架。这是一种尝试不同字体的简单方法,可以了解它们如何利用屏幕空间来换取显示屏的可读性。
Holding down the Shift key while clicking the left mouse button takes you to a menu of fonts. Selecting one of these instantly changes the Emacs font for the current frame and redisplays the frame. This is an easy way to experiment with different fonts to see how well they trade screen space for readability on your display.
多个模块 Emacs 具有文本突出显示和语法着色功能。各种编程和标记语言模式(Lisp模式、Java模式、HTML模式等)都有这样的突出显示。如何自定义这些字体和颜色在很大程度上取决于各个模块。
A number of modules in Emacs feature text highlighting and syntax coloring. The various programming and markup language modes (Lisp mode, Java mode, HTML mode, and so on) have such highlighting. How you customize those fonts and colors depends heavily on the individual module.
Isearch 设施位于 随着 Emacs 的成熟,它经历了一些变化。当您搜索单词或表达式时,它使用字体和颜色来突出显示文档。您可能会发现默认选项有点,嗯,很明显。您可以通过键入Mxcustomize-group输入isearch-faces Enter 来更改它们来自定义组 。
The Isearch facility in Emacs has undergone a few changes as it has matured. It uses font faces and coloring to highlight a document when you search for words or expressions. You may find the default choices a bit, well, stark. You can customize the group by typing M-x customize-group Enter isearch-faces Enter to change them.
顺便说一句,您可能只是尝试更改它用来突出显示次要匹配项的面孔,以便减少干扰。
Incidentally, you might just try changing the face it uses to highlight the secondary matches, so that it's less intrusive.
最简单的使用方法 字体和颜色是加载 Lisp 包font-lock.el(包含在 Emacs 发行版中)。此模式尝试使用颜色和不同的面来突出显示文本缓冲区的有趣功能。举个例子,尝试在 C 和 Lisp 缓冲区中挑选注释,并将它们涂成与代码的基本黑色形成对比的颜色。
The easiest way to use fonts and colors is to load the Lisp package font-lock.el (included with the Emacs distribution). This mode tries to highlight interesting features of your text buffers using color and different faces. As an example, try picking out comments in C and Lisp buffers, and painting them in a color that contrasts with the basic black of the code.
;;每次 Emacs 初始化缓冲区时打开字体锁定模式 ;;对于 Lisp 或 C. ;; (add-hook 'emacs-lisp-mode-hook '打开字体锁定) (add-hook 'c-mode-hook '打开字体锁定)
;; Turn on font lock mode every time Emacs initializes a buffer ;; for Lisp or C. ;; (add-hook 'emacs-lisp-mode-hook 'turn-on-font-lock) (add-hook 'c-mode-hook 'turn-on-font-lock)
字体锁定模式对于编程语言代码或大纲模式文本的着色特别有帮助,而且还为 HTML 文件和 Dired 缓冲区提供有用的结果。事实上,我们发现它很有用,因此您可能想在全局范围内打开它,就像我们 在本章前面的“示例.emacs文件”中所做的那样。如果您想要更多使用字体锁定模式的示例,请参阅第 9 章,了解 Emacs 支持的一些各种编程语言模式。
Font-lock mode tends to be especially helpful for colorizing programming language code or outline mode text but also gives useful results for HTML files and Dired buffers. In fact, we find it useful in so you may want to turn it on globally instead, as we did in "A Sample .emacs file" earlier in this chapter. If you want more examples using font-lock mode, refer back to Chapter 9 on some of the various programming language modes supported by Emacs.
现在您知道如何 使用自定义,您还可以沿着这条路线编辑和更改字体和颜色。开始自定义的简单方法是运行Mxcustomize-group并输入组名称的面孔。 (图 10-10显示了您将看到的组的示例。)
Now that you know how to work with Custom, you can also go that route to edit and alter fonts and colors. The easy way to get started in Custom is to run M-x customize-group and enter faces for the group name. (Figure 10-10 shows a sample of the groups you'll see.)
但如果你只是想改变怎么办 默认的前景色和背景色?嗯,事实证明这很简单。您可以使用Mx set-foreground-color和Mx set-background-color命令来选择简单的颜色(基于它们的名称,例如黑色、白色、黄色、蓝色、红色等)。但要小心,因为 Emacs 会毫不犹豫地让您将这些值设置为花哨的(甚至不可能的)组合!虽然黑色背景上的黑色文本可以提供一定程度的安全性,防止任何人偷看你的肩膀,但从长远来看,这并不是最有效的组合。
But what if you just want to change the default foreground and background colors? Well, that turns out to be quite simple. You can use the M-x set-foreground-color and M-x set-background-color commands to pick simple colors (based on their names such as black, white, yellow, blue, red, etc.). Be careful, though, because Emacs has no qualms about letting you set these values to garish—or even impossible—combinations! While black text on a black background may provide some level of security from anyone peeking over your shoulder, it's not the most productive combination in the long run.
要查看可用颜色的范围,请运行Mx set-foreground-color。当它提示您输入颜色时,只需按 Tab 键即可获取可能颜色的完整列表 - 您应该会得到相当多的颜色!这些名称也可以输入到自定义中的前景和背景字段(或任何其他基于颜色的字段)中。
To see the range of colors available, run M-x set-foreground-color. When it prompts you for a color, just press Tab to get a completion list of the possible colors—you should get quite a few! These names can also be typed into the foreground and background fields (or any other color-based field) in Custom.
您还可以使用“自定义”来控制“默认”字体的所有方面(包括前景色和背景色)。图 10-11显示了将颜色切换为绿色和黑色后该字体的自定义屏幕。
You can also use Custom to control all aspects (including the foreground and background colors) of the "default" font. Figure 10-11 shows the Custom screen for just that font after switching the colors to green and black.
图 10-11。对默认字体颜色的更改有效地设置了 Emacs (Mac OS X) 的前景色和背景色
Figure 10-11. Changes to the default font colors effectively set the foreground and background colors for Emacs (Mac OS X)
您可以通过前面讨论的常用渠道来自定义此面孔,或者直接使用Mxcustomize-face来到这里,然后在提示符下输入默认值。
You can go through the usual channels discussed previously to customize this face, or come here directly with M-x customize-face and then enter default at the prompt.
聪明的读者一定会注意到, 尽管突出显示机制允许我们在缓冲区中设置丰富的文本,但我们还没有展示一种在会话之间保存文本属性和文本的方法。这是一个重大问题。只要没有办法将属性与文本一起保存,所有的字体和颜色机制就只不过是一种显示黑客,有利于装饰缓冲区,但对 Emacs 的编辑能力几乎没有增加。
The astute reader will have noticed that, although the highlighting machinery allows us to set up enriched text in a buffer, we haven't shown a way to save text properties along with text between sessions. This is a significant issue. As long as there is no way to save properties along with text, all the font and color machinery remains little more than a display hack, good for decorating buffers but adding little to Emacs's editing power.
解决这种情况需要一种方法,将文本属性保存在扩展文本标记表单中,并在下次编辑文件时将其恢复到文本属性中。
What's needed to remedy this situation is a way for text properties to be saved in an expanded text-markup form and restored into text properties when the file is next edited.
在撰写本文时,Emacs 中包含了支持此功能的实验代码。一个名为丰富模式的库 支持将文本属性保存为 Internet 标准文档 RFC 1896 指定的 MIME 丰富文本格式,并且可以将该格式的文件解析到具有等效文本和文本属性的 Emacs 缓冲区中。
At the time of this writing, experimental code to support this is included with Emacs. A library called enriched-mode supports saving text properties into the MIME enriched-text format specified by the Internet standards document RFC 1896, and can parse files in that format into Emacs buffers with equivalent text and text properties.
尽管这种模式非常有用,但在功能丰富的模式支持成熟并与其他 Emacs 模式良好集成之前,仍然需要完成大量的设计和开发。当您阅读本文时,可能已经有多个这样的库,每个库都支持不同的丰富格式,例如 HTML。最终,像这样的模式将使 Emacs 支持所见即所得甚至多媒体编辑。
Although this mode is quite usable as is, much design and development still needs to be done before the capabilities enriched mode supports are mature and well integrated with other Emacs modes. By the time you read this, there may be several such libraries, each supporting a different enriched format such as HTML. Eventually modes like these should enable Emacs to support WYSIWYG and even multimedia editing.
要进入丰富模式,请输入Mx riched-mode。Enriched出现在模式行上。 Emacs 可能会询问您是否要在段落之间设置换行符。 (这是因为当您更改边距设置时,Emacs 会重新格式化段落。)输入y。
To enter enriched mode, type M-x
enriched-mode. Enriched appears on the
mode line. Emacs may ask if you want to make newlines between
paragraphs hard. (This is because Emacs reformats the paragraphs when
you change margin settings.) Type y.
您可以使用多种字体命令来装饰文本。大多数以Mg前缀开头。表 10-1 列出了一些更常见的选项。如果您喜欢使用菜单,也可以选择 使用编辑→文本属性 →面菜单选择表 10-1中的选项。
You can use several font commands to decorate your text. Most begin with the M-g prefix. Table 10-1 lists some of the more common options. If you like using the menus, you can also select the options in Table 10-1 using the Edit → Text Properties → Face menu.
表 10-1。丰富模式字体命令
Table 10-1. Enriched mode font commands
|
命令 Command |
已选择字体 Font selected |
|---|---|
|
镁 M-g d |
默认 default |
|
镁b M-g b |
大胆的 bold |
|
镁 M-g i |
斜体 italic |
|
镁升 M-g l |
加粗斜体 bold-italic |
|
镁 M-g u |
强调 underline |
|
镁氧 M-g o |
其他(允许您按名称选择字体) other (allows you to pick a font face by name) |
表 10-1中列出的命令适用于当前标记的文本。我们使用了许多这样的命令来生成如图 10-12所示的简单文本示例。
The commands listed in Table 10-1 apply to the currently marked text. We used a number of these commands to produce the simple text example shown in Figure 10-12.
当您保存丰富的文本时,Emacs 使用类似 XML 的标签来标记文档。 Emacs 会很乐意读回文档,尽管没有多少其他应用程序知道如何处理标签。尽管如此,正如您在下面看到的,这些标签很简单,并且允许自定义应用程序(例如用于 Web 的 CGI 脚本)快速解析它们。
When you save enriched text, Emacs marks up the document with XML-like tags. Emacs will happily read the document back in, although not many other applications will know what to do with the tags. Still, as you can see below, the tags are straightforward and would allow custom applications such as CGI scripts for the Web to parse them quickly.
内容类型:文本/丰富 文本宽度:70 <x-color><param>蓝色</param>测试</x-color> 这是一个快速测试 Emacs 中的 <x-color><param>red</param>enriched</x-color> 模式。 <bold>不确定会发生什么。</bold> 从这里看起来不错。
Content-Type: text/enriched Text-Width: 70 <x-color><param>blue</param>Testing</x-color> This is a quick test of the <x-color><param>red</param>enriched</x-color> mode in Emacs. <bold>Not sure what's gonna happen.</bold> Looks good from here.
但是,您还不能过度依赖丰富模式。例如,注意Testing标题行。它似乎不包含任何有关字体大小的信息——如果你看一下图 10-11,字体肯定会更大。果然,杀死缓冲区并重新加载文件会丢失大小值。文本仍为蓝色,内容可用,但部分格式已丢失。
But, you can't rely too much on enriched mode yet.
For example note the Testing title line. It
doesn't appear to contain any information about the
size of the font—which is definitely larger if you look at
Figure 10-11. Sure enough, killing the buffer and reloading the file
loses the size value. The text is still blue and the content is
available, but some of the formatting has been lost.
这是一个经典的寓言:小心。如果您有严重的丰富文本需求,Emacs 可能不是适合使用的工具(至少现在还不是)。许多不同的文字处理程序可以做得更好。但是,如果您只需要对只有您或其他 Emacs 用户才能查看的文档进行一些基本增强,那么丰富模式就是您的最佳选择。
The moral is a classic one: be careful. If you have serious enriched text needs, Emacs is probably not the tool to use (at least not yet). Many of the various word processors out there will do a much better job. But if you just need some basic enhancements to documents that only you or other Emacs users will view, enriched mode is just the ticket.
也许最常见的事情 Emacs 用户想要自定义的是导致命令运行的击键。击键通过键绑定与命令相关联。
Perhaps the most common things that Emacs users want to customize are the keystrokes that cause commands to run. Keystrokes are associated with commands via key bindings.
实际上,每次击键都会在 Emacs 中运行一个命令。可打印字符键(字母、数字、标点符号和空格)运行 selfinsert-command,这只会导致刚刚按下的键插入当前缓冲区中的光标处。 (您可以通过更改可打印字符的绑定来对天真的 Emacs 用户开一个令人讨厌的愚人节玩笑。)
Actually, every keystroke runs a command in Emacs. Printable character keys (letters, numerals, punctuation, and spaces) run the self-insert-command, which merely causes the key just pressed to be inserted at the cursor in the current buffer. (You could play a nasty April Fool's joke on a naïve Emacs user by changing the bindings of their printable characters.)
当然,默认的键绑定集足以满足大多数用途,但在多种情况下您可能需要添加或更改键绑定。 Emacs 实际上包含数百个命令,其中只有一些具有键绑定。如您所知,您可以通过键入Mx command-name Enter来访问那些没有绑定的内容。
The default set of key bindings is adequate for most purposes, of course, but there are various cases in which you may want to add or change key bindings. Emacs contains literally hundreds of commands, only some of which have key bindings. As you know, you can access those that don't have bindings by typing M-x command-name Enter.
但是,如果您打算经常使用未绑定的命令,则为了方便起见,您可能需要将其绑定到击键序列。您可能需要设置特殊键(例如箭头、数字键盘或功能键)来执行经常使用的命令。
If, however, you intend to use an unbound command often, you may want to bind it to a keystroke sequence for convenience. You may want to set special keys, such as arrow, numeric keypad, or function keys, to perform commands you use often.
您现在需要了解的另一个重要概念是 keymap ,它是键绑定的集合。 Emacs 中最基本的默认键绑定保存在名为global-map的键映射中。还有本地键盘映射的概念,它特定于单个缓冲区。本地键盘映射用于在模式(如 C 模式、文本模式、shell 模式等)中实现命令,每个此类模式都有自己的键盘映射,在调用时将其安装为本地映射。当您键入一个键时,Emacs 首先在当前缓冲区的本地映射(如果有)中查找它。如果在那里找不到条目,它会在global-map中查找。如果找到该键的条目,则运行其关联的命令。
The other important concept you need to know now is that of a keymap, which is a collection of key bindings. The most basic default key bindings in Emacs are kept in a keymap called global-map. There is also the concept of a local keymap, which is specific to a single buffer. Local keymaps are used to implement commands in modes (like C mode, text mode, shell mode, etc.), and each such mode has its own keymap it installs as the local map when invoked. When you type a key, Emacs first looks it up in the current buffer's local map (if any). If it doesn't find an entry there, it looks in global-map. If an entry for the key is found, its associated command is run.
绑定到多次击键的命令会发生什么情况,例如Cx k中的Kill-buffer?答案是 Cx、Esc和Cc键 实际上绑定到特殊的内部函数,这些函数会导致 Emacs 等待按下另一个键,然后在另一个映射中查找该键的绑定;如果在按下下一个键之前超过一秒,它们还会导致像Cx-这样的消息出现在迷你缓冲区中。 Cx和Esc的附加键映射 分别 称为ctl-x-map和 esc-map,[ 1 ] ; Cc保留用于与 C 模式和 shell 模式等模式相关的本地键盘映射。
What happens with commands that are bound to multiple keystrokes, as in C-x k for kill-buffer? The answer is that the keys C-x, Esc, and C-c are actually bound to special internal functions that cause Emacs to wait for another key to be pressed and then to look up that key's binding in another map; they also cause messages like C-x- to appear in the minibuffer if more than a second passes before the next key is pressed. The additional keymaps for C-x and Esc are called ctl-x-map and esc-map,[1] respectively; C-c is reserved for local keymaps associated with modes like C mode and shell mode.
例如,当您键入Esc d或 Md时,Emacs 会在缓冲区的本地键盘映射中查找它。我们假设它在那里找不到条目。然后 Emacs 搜索 global-map;它在那里找到一个带有特殊函数(称为ESC-prefix )的Esc条目,该函数等待下一次击键并使用esc-map 来确定要执行哪个命令。当您键入d时,ESC-prefix会在esc-map中 查找d 的条目,找到kill-word并运行它。
For example, when you type Esc d or M-d, Emacs looks it up in the buffer's local keymap. We will assume it doesn't find an entry there. Then Emacs searches global-map; there it finds an entry for Esc with a special function (called ESC-prefix) that waits for the next keystroke and uses esc-map to determine which command to execute. When you type d, ESC-prefix looks up the entry for d in esc-map, finds kill-word, and runs it.
您可以通过在键映射中添加条目(或覆盖现有条目)来创建自己的键绑定。可以使用三个函数来执行此操作:define-key、global-set-key和local-set-key。它们的形式是:
You can create your own key bindings by adding entries in keymaps (or overriding existing ones). Three functions are available for doing this: define-key, global-set-key, and local-set-key. Their forms are:
(定义键keymap“keystroke”' ) (全局设置键“ ”' )command-namekeystrokecommand-name(本地设置键“击键”'命令名称)
(define-keykeymap"keystroke" 'command-name) (global-set-key "keystroke" 'command-name) (local-set-key "keystroke" 'command-name)
请注意击键周围的双引号和命令名称前面的单引号。这是 Lisp 语法;详细信息请参见第 11 章。按键是一个或多个字符,可以打印或特殊字符。对于后者,请使用表 10-2中的约定。
Notice the double quotes around keystroke and the single quote preceding command-name. This is Lisp syntax; for more details, see Chapter 11. The keystroke is one or more characters, either printable or special characters. For the latter, use the conventions in Table 10-2.
表 10-2。特殊字符约定
Table 10-2. Special character conventions
|
特殊字符 Special character |
定义 Definition |
|---|---|
|
\Cx \C-x |
Cx(其中 x 是任意字母) C-x (where x is any letter) |
|
\核 \C-[ or \e |
Esc键 Esc |
|
\米 \M |
元 Meta |
|
\Cj 或 \n \C-j or \n |
新队 Newline |
|
\Cm 或 \r \C-m or \r |
进入 Enter |
|
\Ci 或 \t \C-i or \t |
标签 Tab |
因此,字符串abc\Ca\ndef等于abc、Ca、newline和def,全部连接成一个字符串。请注意,控制字符不区分大小写,即\CA与\Ca相同 。但是,控制字符后面的字符可能区分大小写;例如,\C-ae可能与\C-aE不同。
Thus, the string abc\C-a\ndef is equal to abc, C-a, newline, and def, all concatenated into one string. Note that control characters are case-insensitive—that is, \C-A is the same thing as \C-a. However, the characters that follow control characters may be case-sensitive; \C-ae could be different from \C-aE, for example.
函数define-key是最通用的,因为它可用于绑定任何键盘映射中的键。global-set-key仅绑定全局映射中的键;由于只有一个global-map,(global-set-key ...)与(define-key global-map ...)相同。函数 local-set-key绑定当前缓冲区本地映射中的键;它仅适用于在 Emacs 会话期间指定临时键绑定。
The function define-key is the most general because it can be used to bind keys in any keymap. global-set-key binds keys in the global map only; since there is only one global-map, (global-set-key ...) is the same as (define-key global-map ...). The function local-set-key binds keys in the local map of the current buffer; it is useful only for specifying temporary key bindings during an Emacs session.
这是一个简单的键盘自定义示例。假设您正在用编程语言编写代码。您编译它并收到包含错误行号的错误消息,并且您希望转到源文件中的该行来更正错误。[ 2 ]您可能需要使用goto-line命令,默认情况下该命令不绑定到任何击键。假设您想将其绑定到Cx l。放入 .emacs文件的命令是
Here is an example of a simple keyboard customization. Let's say you are writing code in a programming language. You compile it and get error messages that contain the line number of the error, and you want to go to that line in the source file to correct the error.[2] You would want to use the goto-line command, which is not bound by default to any keystroke. Say you want to bind it to C-x l. The command to put into your .emacs file is
(全局设置键“\C-xl”'转到行)
(global-set-key "\C-xl" 'goto-line)
这会将ctl-x-map中的l槽全局绑定到函数goto-line(即在所有模式下)。或者,您可以使用以下任一方法:
This binds the l slot in ctl-x-map to the function goto-line globally—that is, in all modes. Alternatively, you can use either of the following:
(定义键全局映射“\C-xl”'转到行) (define-key ctl-x-map "l" '转到行)
(define-key global-map "\C-xl" 'goto-line) (define-key ctl-x-map "l" 'goto-line)
这些命令具有相同的效果,但实际上并没有更有效或更好。实际上,您不必知道Cx的键盘映射称为ctl-x-map。我们将坚持在其余示例中显示全局设置键方法,但请记住,您可以在不适合设置全局键的情况下使用定义键,例如添加特定于模式的击键时。
These commands have the same effect but aren't really any more efficient or better. And really, you shouldn't have to know that the keymap for C-x is called ctl-x-map. We'll stick to showing the global-set-key approach for the remaining examples, but remember that you have define-key available for situations where setting the global key is not appropriate, such as when adding a mode-specific keystroke.
键重新绑定的其他示例包括绑定Cx ?为help-command,Ch为backward-char。这些键重新绑定如下所示:
Other examples of key rebindings include binding C-x ? to help-command and C-h to backward-char. These key rebindings are shown below:
(全局设置键“\Cx?”'帮助命令) (全局设置键“\Ch”'向后字符)
(global-set-key "\C-x?" 'help-command) (global-set-key "\C-h" 'backward-char)
请注意,这些也可以完成为
Notice that these could also be done as
(define-key ctl-x-map "?" '帮助命令) (定义键全局映射“\Ch”'向后字符)
(define-key ctl-x-map "?" 'help-command) (define-key global-map "\C-h" 'backward-char)
将键绑定(或任何其他代码)放入 .emacs文件后,您需要“运行”(或评估)该文件以使更改生效。其命令是Mx eval-current-buffer Enter。更好的是,你可以按Cx Ce,这(我们将在下一章中看到)只会导致你的光标所在的单行 Lisp 代码运行。如果您不执行其中任何一项操作,则更改将在您下次调用 Emacs 时才会生效。
After you put a key binding (or any other code) in your .emacs file, you need to "run" (or evaluate) the file for the change to take effect. The command for this is M-x eval-current-buffer Enter. Even better, you could press C-x C-e, which (as we will see in the next chapter) causes only the single line of Lisp code that your cursor is on to run. If you don't do either of these, the changes won't take effect until the next time you invoke Emacs.
更复杂的键盘 自定义任务是将命令绑定到键盘上的特殊键,例如箭头、数字键盘或功能键。这种级别的自定义需要一些工作,但如果您喜欢使用特殊键,那么这是非常值得的。
A more complicated keyboard customization task is binding commands to special keys, such as arrow, numeric keypad, or function keys, on your keyboard. This level of customization takes some work, but if you like using special keys, it is well worth the effort.
大多数特殊键都有合理的名称,但将它们与上面讨论的设置键函数一起使用需要使用稍微不同的语法。键的名称出现在方括号内而不是双引号内。例如,您可以将 goto-line命令绑定到功能键 F5,如下所示:
Most of the special keys have reasonable names, but using them with the set key functions discussed above requires using a slightly different syntax. The name of the key appears inside square brackets rather than inside double quotes. For example, you could bind the goto-line command to the function key F5 like this:
(全局设置键 [f5] '转到行)
(global-set-key [f5] 'goto-line)
您当然可以将修饰符与特殊键一起使用。 Control-Alt-F5 可以这样绑定:
And you can certainly use modifiers with your special keys. Control-Alt-F5 can be bound like this:
(全局设置键 [CA-f5] '转到行)
(global-set-key [C-A-f5] 'goto-line)
一些常用特殊键的名称如表10-3所示。
Table 10-3 lists the names of some common special keys.
表 10-3。特殊键 ELisp 名称
Table 10-3. Special key ELisp names
|
ELISP名称 ELisp Name |
钥匙 Key |
ELISP名称 ELisp Name |
钥匙 Key | |
|---|---|---|---|---|
|
DEL 或退格键 DEL or backspace |
退格键 Backspace |
kp-0 .. kp-9 kp-0 .. kp-9 |
键盘数字 0 到 9 Keypad numbers 0 through 9 | |
|
删除 delete |
删除键 Delete key |
kp-输入 kp-enter |
数字键盘上的 Enter 键 Enter key on the number pad | |
|
向下 down |
向下箭头键 Down arrow key |
左边 left |
左箭头键 Left arrow key | |
|
结尾 end |
结束键 End key |
下一个 next |
向下翻页 Page Down | |
|
f1 .. f35 f1 .. f35 |
功能键 F1 至 F35 Function keys F1 through F35 |
事先的 prior |
向上翻页 Page Up | |
|
家 home |
家里的钥匙 Home key |
正确的 right |
右箭头键 Right arrow key | |
|
帮助 help |
帮助键 Help key |
向上 up |
向上箭头键 Up arrow key |
您还可以删除一个与global-unset-key和Define-key命令的特定键绑定。例如,以下几行都将从前面的示例中删除goto-line命令绑定:
You can also remove a particular key binding with the global-unset-key and define-key commands. For example, the following lines will both remove the goto-line command bindings from our previous examples:
(全局取消设置键 [f5]) (define-key ctl-x-map "l" nil)
(global-unset-key [f5]) (define-key ctl-x-map "l" nil)
当然,如果您打算用其他东西替换它们,则不需要取消设置任何绑定。但是,如果您有一个常见的“打字错误”键,并且您不希望在错误输入时触发该键,那么这可能会很有用。
Of course, you don't need to unset any bindings if you plan to replace them with something else. But this can be useful if you have a common "typo" key that you don't want firing off when you type it by mistake.
现在我们将进入 影响 Emacs 行为的方法——而不仅仅是它的用户界面。最简单的方法是设置控制各种事物的变量。我们已经在第 2 章中看到了类似 自动保存间隔的示例。要设置变量的值,请 在 .emacs中使用setq函数,如下所示:
Now we will get into ways to affect Emacs' behavior—not just its user interface. The easiest way to do so is by setting variables that control various things. We already saw examples of this like auto-save-interval in Chapter 2. To set the value of a variable, use the setq function in your .emacs, as in:
(setq 自动保存间隔 800)
(setq auto-save-interval 800)
虽然auto-save-interval采用 整数(数字)值,但许多 Emacs 变量采用 true 或 false 值,在计算机术语中称为布尔值。在 Emacs Lisp 中,t 是真值,nil是假值,尽管在大多数情况下,除了nil之外的任何值都被视为真值。 Emacs 变量可以采用其他类型的值,以下是指定它们的方法:
Although auto-save-interval takes an integer (number) value, many Emacs variables take true or false values, called Boolean in computer parlance. In Emacs Lisp, t is the true value, and nil is the false value, although in most cases, anything other than nil is taken to mean true. Emacs variables can take other types of values, and here is how to specify them:
Strings of characters are surrounded by double quotes. We saw examples of strings in the arguments to key binding commands earlier in this chapter.
Characters are specified like strings but with a ? preceding them, and they are not surrounded by double quotes. Thus, ?x and ?\C-c are character values x and C-c, respectively.
符号由单个给出 引号后跟符号名称 - 例如, ' never (请参阅附录 A中的变量版本控制)。
Symbols are given by a single quote followed by a symbol name—for example, 'never (see the variable version-control in Appendix A).
附录 A中显示了有用的 Emacs 变量列表(按类别分组) ,以及说明和默认值。 Emacs 有超过 2,500 个变量 — 比附录 A中涵盖的变量多得多。如果您想要自定义 Emacs 的某些内容,则变量可能会控制该功能(特别是如果您想要更改的内容涉及数字或真或假条件)。要查明是否有任何变量与您想要执行的操作相关,您可以使用 第 14 章中描述的apropos-variable命令来查找变量及其描述。
A list of useful Emacs variables, grouped by category, appears in Appendix A, with descriptions and default values. Emacs has more than 2,500 variables—many more than are covered in Appendix A. If there is something about Emacs that you want to customize, a variable probably controls the feature (especially if what you want to change involves a number or a true-or-false condition). To find out whether any variables relate to what you want to do, you can use the apropos-variable command described in Chapter 14 to look for variables and their descriptions.
每个缓冲区的多个 Emacs 变量可以有不同的值(用 Emacs 的说法是本地值)以及 默认值。此类变量在未指定本地值的缓冲区中采用默认值。一个常见的例子是开始一个新的文本文档。left-margin变量的本地值尚未设置,因此 Emacs 使用left-margin的默认值。如果您愿意,可以更改此缓冲区中的本地值。但是在新的缓冲区中启动一个新文档,您会发现左边距又回到了默认值——因为第二个缓冲区的本地值尚未设置。
Several Emacs variables can have different values for each buffer (local values, in Emacs parlance) as well as a default value. Such variables assume their default values in buffers where the local values are not specified. A common example is starting a new text document. The local value for the left-margin variable has not been set, so Emacs uses the default value for left-margin. You can change the local value in this buffer if you like. But start a new document in a new buffer and you'll find that left-margin is back to the default value—because the second buffer's local value has not been set.
正如您所期望的,您可以设置此类变量的默认值和本地值。当您使用setq设置变量的值(例如 left-margin或case-fold-search)时,您实际上是在设置本地值。设置默认值的方法是使用setq-default而不是setq,如下所示:
As you might expect, you can set both the default and local values of such variables. When you set the value of a variable such as left-margin or case-fold-search with setq, you are actually setting the local value. The way to set default values is to use setq-default instead of setq, as in:
(setq-默认左边距 4)
(setq-default left-margin 4)
不幸的是,没有一种通用的方法可以判断一个变量是否只有一个全局值,或者有默认值和局部值(当然,除了查看模式的 Lisp 代码)。因此,最好的策略是使用普通的setq, 除非您从经验中发现特定变量似乎不具有您设置的值,在这种情况下您应该使用setq-default。例如,如果您输入以下行:
Unfortunately, there is no general way to tell whether a variable has just one global value or has default and local values (except, of course, by looking at the Lisp code for the mode). Therefore the best strategy is to use a plain setq, unless you find from experience that a particular variable doesn't seem to take on the value you setq it to—in which case you should use setq-default. For example, if you put the line:
(setq 大小写折叠搜索 nil)
(setq case-fold-search nil)
在你的.emacs文件中,你会发现 Emacs 仍然忽略搜索命令中的大小写差异,就好像这个变量仍然是t;相反,您应该使用setq-default。
in your .emacs file, you will find that Emacs still ignores case differences in search commands as if this variable were still t; instead, you should use setq-default.
Emacs 包含大量 Lisp 代码;事实上,作为 我们将在第 11 章中看到,Emacs 的大部分内置功能都是用 Lisp 编写的。 Emacs 还附带了几个额外的 Lisp包(也称为 库),您可以引入(或 加载)它们来添加更多功能。 Lisp 软件包一直被添加到 Emacs 中,有时您的系统管理员会添加从自由软件基金会以外的来源获得的软件包。
Emacs contains lots of Lisp code; in fact, as we will see in Chapter 11, the majority of Emacs' built-in functionality is written in Lisp. Emacs also comes with several extra Lisp packages (also known as libraries) that you can bring in (or load) to add more features. Lisp packages are being added to Emacs all the time, and sometimes your system administrator will add packages obtained from sources other than the Free Software Foundation.
附录 B 列出了最有用的内置Lisp 包,以及如何使用它们的说明。您还可以通过键入Ch p(按关键字查找)来获取有关系统上可用的软件包的信息。简而言之,内置包执行以下操作:
Appendix B lists the most useful built-in Lisp packages, along with explanations of how to use them. You can also get information about which packages are available on your system by typing C-h p (for finder-by-keyword). Briefly, the built-in packages do the following kinds of things:
支持 C、Lisp、Perl、Java 和其他几种语言编程(参见第 9 章)。
Support programming in C, Lisp, Perl, Java, and several other languages (see Chapter 9).
支持使用 TEX、LATEX、XML 和 HTML 进行文本处理(参见第 8 章)。
Support text processing with TEX, LATEX, XML, and HTML (see Chapter 8).
模拟其他编辑器(vi、EDT和 Gosling Emacs)。
Emulate other editors (vi, EDT, and Gosling Emacs).
与操作系统实用程序的接口,例如 shell(请参阅第 5 章)。
Interface to operating system utilities, such as the shell (see Chapter 5).
提供编辑支持功能,例如拼写检查(参见第 3 章)和大纲编辑(参见第 7 章)以及文本排序、命令历史编辑、Emacs 变量设置(参见附录 A)等等。
Provide editing support functions, such as spell checking (see Chapter 3) and outline editing (see Chapter 7) as well as text sorting, command history editing, Emacs variable setting (see Appendix A), and much more.
玩各种游戏并提供其他形式的娱乐。
Play various games and provide other forms of amusement.
详细信息请参见附录 B。
See Appendix B for more details.
附录 B中的表格列出了 当您访问名称以适当后缀结尾的文件时,会自动调用几种主要模式。在表的右侧列中查找“后缀”,可以看到文件名后缀与 Emacs 默认设置的主要模式之间的许多关联。这些关联包含在特殊的 Emacs 变量auto-mode-alist中。auto-mode-alist是一个对的列表 ( regexp . mode ),其中 regexp是正则表达式(参见 第3 章和第 11 章),mode是调用主模式的函数的名称。当 Emacs 访问文件时,它会(从头开始)搜索该列表以查找与文件后缀匹配的正则表达式。如果找到,它就会运行关联的模式函数。请注意,文件名的任何部分(不仅仅是后缀)实际上都可以与主模式关联。
The tables in Appendix B list several major modes that are automatically invoked when you visit a file whose name ends in the appropriate suffix. Look for "suffix" in the right-hand columns of the tables to see many of the associations between filename suffixes and major modes that Emacs sets up by default. These associations are contained in the special Emacs variable auto-mode-alist. auto-mode-alist is a list of pairs (regexp . mode), where regexp is a regular expression (see Chapter 3 and Chapter 11) and mode is the name of a function that invokes a major mode. When Emacs visits a file, it searches this list (from the beginning) for a regular expression that matches the file's suffix. If it finds one, it runs the associated mode function. Notice that any part of a file's name—not just its suffix—can actually be associated with a major mode.
你可以将自己的关联添加到auto-mode-alist中,尽管如果你不习惯 Lisp,语法会很奇怪(有关详细信息,请参阅第 11 章)。如果您使用 Ada 语言进行编程,并且您的 Ada 编译器需要带有后缀 .ada的文件,那么您可以通过在.emacs文件中添加以下行,让 Emacs 在您每次访问文件时将其置于 Ada 模式 :
You can add your own associations to auto-mode-alist, although the syntax is weird if you are not used to Lisp (see Chapter 11 for the gory details). If you are programming in the Ada language, and your Ada compiler expects files with suffix .ada, you can get Emacs to put your files in Ada mode whenever you visit them by putting the following line in your .emacs file:
(setq 自动模式列表 (cons '("\\.ada$" .ada-mode) 自动模式列表))(setq auto-mode-alist (cons '("\\.ada$" . ada-mode) auto-mode-alist))确保在术语后面包含单引号
以及“ \\ . ”和.cons之间的点。符号 '只是 Lisp 语法,表示“使 x 和 ya 配对”。字符串“ ”是一个正则表达式,意思是“末尾带有.ada的任何内容”,即匹配字符串的结尾(而不是行尾,这是在正则表达式搜索期间匹配的内容)并更换)。 Lisp 的整行基本上意味着“将对添加
到自动模式列表的前面”。请注意,由于 Emacs
从头开始搜索auto-mode-alist,并在找到匹配项时停止,因此您可以使用上面的cons构造来覆盖现有的模式关联。[ 3 ]ada$ada-mode(x . y)\\.ada$$("\\.ada$", 'ada-mode)
Make sure you include the single quote after the term
cons and the dot between "\\.ada$" and ada-mode. The
notation '(x . y) is just Lisp syntax for
"make x and y a pair." The string
"\\.ada$" is a regular expression that means
"anything with .ada at the end
of it," that is, $ matches the
end of the string (as opposed to the end of the line, which is what
it matches during regular expression search and replace). The entire
line of Lisp basically means "add the pair
("\\.ada$", 'ada-mode) to the front of the
auto-mode-alist." Note that, because Emacs searches
auto-mode-alist from the beginning
and stops when it finds a match, you can use the above cons construct to override existing mode
associations.[3]
再举一个例子,假设您将某些邮件消息保存在名称以msg-开头的文件中,并且您希望以文本模式编辑这些文件。方法如下:
As another example, let's say you save certain mail messages in files whose names begin with msg-, and you want to edit these files in text mode. Here is the way to do it:
(setq 自动模式列表 (cons '("^msg-" . 文本模式) 自动模式列表))(setq auto-mode-alist (cons '("^msg-" . text-mode) auto-mode-alist))请注意,在这种情况下,我们匹配 文件名的开头而不是结尾。正则表达式运算符 ( ^ ) 表示字符串的开头,因此整个正则表达式表示“以 msg- 开头的任何内容”。
Notice that in this case we are matching the beginning, rather than the end, of the filename. The regular expression operator (^) means beginning of string, so the entire regular expression means "anything beginning with msg-."
最后,如果您正在编辑的文件名与auto-mode-alist中的任何正则表达式都不匹配,Emacs 会将其置于名称为变量 default-major-mode值的模式中。该模式通常是基本模式,即没有特殊功能的基本模式。然而,许多人喜欢将默认模式设置为文本模式,通过在.emacs中添加如下行来完成 :
Finally, if the name of a file you are editing does not match any of the regular expressions in auto-mode-alist, Emacs puts it into the mode whose name is the value of the variable default-major-mode. This mode is normally fundamental mode, a basic mode without special functionality. However, many people like to set their default mode to text mode, accomplished by adding a line like this to .emacs:
(setq 默认主要模式 '文本模式)
(setq default-major-mode 'text-mode)
尽管我们在本章中介绍了许多自定义 Emacs 的有用方法,但我们实际上只触及了表面。要了解更多信息,请参阅第 11 章并了解 Lisp 编程,这是让 Emacs 做任何你想做的事情的关键。
Although we have covered many useful ways to customize Emacs in this chapter, we have really only scratched the surface. To find out more, turn to Chapter 11 and find out about Lisp programming, the key to getting Emacs to do just about anything you want.
Emacs 不仅具有针对每个用户的定制功能;它还可以进行站点范围的定制。如果 Emacs 没有按照您的预期进行操作,您可能需要尝试通过在不进行自定义的情况下启动 Emacs 来禁止任何全局自定义文件。
Emacs not only has per-user customizations; it can also have sitewide customizations. If Emacs isn't doing what you expect it to, you might want to try inhibiting any global customization file by starting Emacs with no customization.
您可以使用一个来做到这一点 当您调用 Emacs 时,这些命令行选项。
You can do that by using one of these command-line options when you invoke Emacs.
--no-init-file,既不加载 ~/.emacs 也不加载 default.el -q
--no-init-file, -q
load neither ~/.emacs nor default.el
--no-site-file
不加载 site-start.el
--no-site-file
do not load
site-start.el
如果您通常从图标启动 Emacs,那么在这种情况下了解如何从命令行启动它会很有帮助。 (如果.emacs文件在更改后变得混乱,有时您可能还想使用 -debug选项来帮助您找出问题所在。)第 13 章介绍了如何从 Mac OS X 的命令行启动 Emacs 和Windows 用户。
If you normally start Emacs from an icon, it's
helpful to learn how to start it from the command-line for cases like
this. (You may also want to use the -debug option
sometime to help you figure out what's wrong with
your .emacs file if it is messed up following a
change.) Chapter 13 describes how to start Emacs
from the command-line for Mac OS X and Windows users.
您还可以通过在主目录中创建一行 .emacs文件来禁止全局初始化。它应该看起来像这样:
You can also inhibit global initialization by creating a one-line .emacs file in your home directory. It should look exactly like this:
(setq 抑制-默认-初始化 t);没有全局初始化
(setq inhibit-default-init t) ; no global initialization
再次启动 Emacs。该文件阻止 Emacs 读取其全局初始化文件。
Start Emacs again. This file prevents Emacs from reading its global initialization file.
还有一个尴尬的情况:如果你坐在别人的系统前怎么办?您启动 Emacs,突然间您面临着其他人的“私有”键绑定和功能。即使在这种情况下,也有一个解决方案:
There's still one awkward situation: what if you're sitting down at someone else's system? You start Emacs, and all of a sudden you're faced with someone else's "private" key bindings and features. Even in this situation, there's a solution:
尝试使用命令emacs -q。-q选项 告诉 Emacs在启动之前不要读取用户的.emacs文件。通过这样做,您将避免用户的私人定制。
Try using the command emacs -q. The -q option tells Emacs not to read the user's .emacs file before starting. By doing this, you'll avoid the user's private customizations.
假设在这一步之后,您仍然没有自己的自定义。如果您想让 Emacs 读取您的.emacs文件,即使您使用的是其他人的帐户,也请输入命令emacs -u yourname。例如:emacs -u deb使用用户 Deb 的初始化文件 ( /home/deb/.emacs ) 启动 Emacs。
Let's say that after this step, you still don't have your own customizations. If you want to make Emacs read your .emacs file, even when you're using someone else's account, give the command emacs -u yourname. For example: emacs -u deb starts Emacs with the user Deb's initialization file (/home/deb/.emacs).
除非您所在的网络上的用户具有共享主目录结构,否则该-u选项可能不起作用。它假设您在每个系统上都有相同的主目录,或者在每个系统上都有不同的主目录,并且所有主目录中都有最新的
.emacs文件。
The -u option may not work unless
you're on a network where users have a shared home
directory structure. It assumes either that you have the same home
directory on every system, or that you have a different home
directory on every system and an up-to-date
.emacs file in all of your home directories.
如果这一切都失败了,不要害怕。你有更多的选择。让我们考虑最坏的情况:您在别人的系统上,并且无法从命令行启动 Emacs。继续并启动 Emacs。您可以通过在缓冲区中加载您自己的键绑定文件并使用Mx eval-buffer运行它来临时覆盖其他用户的键绑定。
If all that fails, fear not. You have more options. Let's take the worst case scenario: you're on someone else's system and you can't start Emacs from the command line. Go ahead and start Emacs. You can temporarily overwrite the other user's key bindings by loading up your own key bindings file in a buffer and running it with M-x eval-buffer.
您可能应该使用键绑定和其他变量选项创建一个单独的文件,而不是使用.emacs 文件。这是因为很多时候您的 .emacs文件会请求加载存在于仅适用于您自己的系统的路径上的库。如果您发现自己跳到许多不同的机器上,那么值得努力创建一个便携式“重新绑定”文件并将其放在可访问的位置(例如网页或共享文件服务器)。然后您可以从当前的 Emacs 手动评估它。
You probably should make a separate file with key bindings and other variable options rather than using your .emacs file. That's because many times your .emacs file will have requests to load libraries that exist on a path that works only from your own system. If you find yourself jumping to a lot of different machines, it's worth the effort to create a portable "rebinding" file and put it somewhere accessible like a web page or a shared file server. Then you can evaluate it manually from your current Emacs.
如果您已经使用 Emacs 有一段时间了 当您一直在利用它的一些更高级的功能时,您很可能想到了一些 Emacs 没有做到的有用的东西。尽管 Emacs 有数百个内置命令、数十个包和模式等等,但每个人最终都会遇到一些 Emacs 没有的功能。无论您发现缺少什么功能,都可以使用 Emacs Lisp 进行编程。
If you have been using Emacs for a while and have been taking advantage of some of its more advanced features, chances are that you have thought of something useful that Emacs doesn't do. Although Emacs has hundreds of built-in commands, dozens of packages and modes, and so on, everyone eventually runs into some functionality that Emacs doesn't have. Whatever feature you find missing, you can program using Emacs Lisp.
不过,在深入了解之前,请注意本章并不适合所有人。它适用于那些已经习惯使用 Emacs 并具有一定编程经验(尽管不一定熟悉 Lisp本身)的人。如果您没有这样的经验,您可能想跳过本章;如果您希望 Emacs 做一些特定的事情,您可以尝试寻找友好的 Emacs Lisp 黑客来帮助您编写必要的代码。或者,如果您有点冒险精神,您可以浏览足够多的内容来找到文件模板示例并学习如何安装它 - 它为您提供了一些有用的功能。
Before you dive in, however, note that this chapter is not for everyone. It is intended for people who have already become comfortable using Emacs and who have a fair bit of programming experience, though not necessarily with Lisp per se. If you have no such experience, you may want to skip this chapter; if there is something specific you would like Emacs to do, you might try to find a friendly Emacs Lisp hacker to help you write the necessary code. Or, if you're a little adventurous, you could skim enough to find the file-template example and learn how to install it—it gives you some useful features.
正在培养 Lisp 技能但不一定想阅读整章的读者可能还想查找中间的“示例宝藏”部分,以获取有用的工具,帮助他们快速探索 Emacs 库。
Readers who are building their Lisp skills but don't necessarily want to read the whole chapter might also want to look for the "Treasure Trove of Examples" section in the middle for a useful tool that can help jumpstart their exploration of the Emacs libraries.
请注意,本章并没有涵盖 Lisp 的全部内容。那需要另一本大而厚的书。相反,我们介绍了该语言的基础知识以及在编写 Emacs 代码时经常有用的其他功能。如果您想超越本章,请参阅 随 Emacs 一起分发的《GNU Emacs Lisp 参考手册》 (选择“帮助” → “更多手册” → “Lisp 简介和 Emacs Lisp 参考”),了解有关 Emacs 中特定 Lisp 功能的详细信息。您还可以查阅各种 Lisp 教科书[ 1 ],为该语言本身打下坚实的基础。
Note that we do not cover Lisp in its entirety in this chapter. That would require another large, dense book. Instead, we cover the basics of the language and other features that are often useful in writing Emacs code. If you wish to go beyond this chapter, refer to the GNU Emacs Lisp Reference Manual, distributed with Emacs (choose Help→ More Manuals→ Introduction to Lisp and Emacs Lisp Reference) for details about the specific Lisp features in Emacs. You may also turn to any of the various Lisp textbooks[1] available for a solid grounding in the language itself.
Emacs Lisp 是一个成熟的 Lisp 实现;[ 2 ]因此它比许多文本编辑器中常见的宏或脚本语言更重要。 (其中一位作者完全用 Emacs Lisp 编写了一个小型专家系统。)事实上,您甚至可以将 Emacs 本身视为具有大量内置函数的 Lisp 系统,其中许多函数恰好与文本操作、窗口相关管理、文件 I/O 以及其他对文本编辑有用的功能。 Emacs 的源代码是用 C 语言编写的,实现了 Lisp 解释器、Lisp 原语以及最基本的文本编辑命令;一大层内置 Lisp 代码和库在其之上实现了 Emacs 的其余功能。当前版本的 Emacs 附带了近 250,000 行 Lisp 代码。
Emacs Lisp is a full-blown Lisp implementation;[2] thus it is more than the usual macro or script language found in many text editors. (One of the authors has written a small expert system entirely in Emacs Lisp.) In fact, you could even think of Emacs itself as a Lisp system with lots of built-in functions, many of which happen to pertain to text manipulation, window management, file I/O, and other features useful to text editing. The source code for Emacs, written in C, implements the Lisp interpreter, Lisp primitives, and only the most basic commands for text editing; a large layer of built-in Lisp code and libraries on top of that implements the rest of Emacs's functionality. A current version of Emacs comes with close to 250,000 lines of Lisp.
本章首先介绍 Lisp 与 Java 和 Perl 等常见编程语言相似的方面。这些功能足以让您编写许多 Emacs 命令。然后我们讨论如何将 Lisp 代码与 Emacs 接口,以便您编写的函数可以成为 Emacs 命令。我们将看到各种内置的 Lisp 函数,它们对于编写您自己的 Emacs 命令非常有用,包括那些使用正则表达式的函数;我们对正则表达式进行了解释,扩展了第 3 章的介绍 ,并且面向 Lisp 编程。然后,我们稍微回顾一下 Lisp 的基础知识,涵盖该语言与列表有关的独特功能,并通过提供一个可以在自己的编程中安装和使用的文件模板系统来展示本章的概念如何组合在一起或撰写项目。
This chapter starts with an introduction to the aspects of Lisp that resemble common programming languages like Java and Perl. These features are enough to enable you to write many Emacs commands. Then we deal with how to interface Lisp code with Emacs so that the functions you write can become Emacs commands. We will see various built-in Lisp functions that are useful for writing your own Emacs commands, including those that use regular expressions; we give an explanation of regular expressions that extends the introduction in Chapter 3 and is oriented toward Lisp programming. We then return to the basics of Lisp for a little while, covering the unique features of the language that have to do with lists, and show how this chapter's concepts fit together by presenting a file template system you can install and use in your own programming or writing projects.
最后,我们向您展示如何编写一个简单的主要模式,说明 Emacs Lisp 编程的这一“巅峰”并不难扩展。之后,您将看到自定义 Emacs 内置主要模式是多么容易,而无需更改(甚至查看)实现它们的代码。我们通过描述如何构建你自己的 Lisp 包库来结束这一章。
Finally we show you how to program a simple major mode, illustrating that this "summit" of Emacs Lisp programming isn't so hard to scale. After that, you will see how easy it is to customize Emacs's built-in major modes without having to change (or even look at) the code that implements them. We finish the chapter by describing how to build your own library of Lisp packages.
你可能听说过 Lisp 人工智能(AI)语言。如果您不喜欢人工智能,请不要担心。 Lisp 可能具有不寻常的语法,但它的许多基本功能与您可能见过的更传统语言的功能相似,例如 Java 或 Perl。我们在本章中强调这些特征。在介绍了基本的 Lisp 概念之后,我们将继续构建您可以在 Emacs 中实际使用的各种示例函数。为了尝试这些示例,您应该熟悉第 9 章中讨论的 Emacs Lisp 模式和 Lisp 交互模式。
You may have heard of Lisp as a language for artificial intelligence (AI). If you aren't into AI, don't worry. Lisp may have an unusual syntax, but many of its basic features are just like those of more conventional languages you may have seen, such as Java or Perl. We emphasize such features in this chapter. After introducing the basic Lisp concepts, we proceed by building up various example functions that you can actually use in Emacs. In order to try out the examples, you should be familiar with Emacs Lisp mode and Lisp interaction mode, which were discussed in Chapter 9.
基本要素 在 Lisp 中你需要熟悉的是函数、变量和原子。函数是Lisp 中唯一的程序单元;它们涵盖了过程、子例程、程序甚至其他语言中的运算符的概念。
The basic elements in Lisp you need to be familiar with are functions, variables, and atoms. Functions are the only program units in Lisp; they cover the notions of procedures, subroutines, programs, and even operators in other languages.
函数被定义为上述实体的列表,通常是对其他现有函数的调用列表。所有功能 有返回值(与 Perl 函数和非 void Java 方法一样);函数的返回值只是列表中最后一项的值,通常是最后调用的函数返回的值。另一个函数中的函数调用相当于其他语言中的语句,在本章中我们可以互换使用语句和函数调用。这是函数的语法:
Functions are defined as lists of the above entities, usually as lists of calls to other, existing functions. All functions have return values (as with Perl functions and non-void Java methods); a function's return value is simply the value of the last item in the list, usually the value returned by the last function called. A function call within another function is equivalent to a statement in other languages, and we use statement interchangeably with function call in this chapter. Here is the syntax for function:
(...)function-nameargument1argument2
(function-nameargument1argument2...)
这相当于:
which is equivalent to this:
method_name(argument1, argument2,...);
method_name(argument1, argument2,...);
在爪哇。该语法用于 所有函数,包括与其他语言中的算术或比较运算符等效的函数。例如,为了在 Java 或 Perl 中将 2 和 4 相加,您可以使用表达式 2 + 4,而在 Lisp 中您可以使用以下表达式:
in Java. This syntax is used for all functions, including those equivalent to arithmetic or comparison operators in other languages. For example, in order to add 2 and 4 in Java or Perl, you would use the expression 2 + 4, whereas in Lisp you would use the following:
(+ 2 4)
(+ 2 4)
类似地,当您使用 4 >= 2(大于或等于)时,Lisp 等效项为:
Similarly, where you would use 4 >= 2 (greater than or equal to), the Lisp equivalent is:
(>= 4 2)
(>= 4 2)
Lisp 中的 变量有 与任何其他语言中的类似,只是它们没有 类型。 Lisp 变量可以采用任何类型的值(值本身确实有类型,但变量不会对其可以保存的内容施加限制)。
Variables in Lisp are similar to those in any other language, except that they do not have types. A Lisp variable can assume any type of value (values themselves do have types, but variables don't impose restrictions on what they can hold).
原子的值是 任何类型,包括整数、浮点(实数)、字符、字符串、布尔真值、符号和特殊 Emacs 类型(例如缓冲区、窗口和进程)。各种原子的语法是:
Atoms are values of any type, including integers, floating point (real) numbers, characters, strings, Boolean truth values, symbols, and special Emacs types such as buffers, windows, and processes. The syntax for various kinds of atoms is:
Integers are what you would expect: signed whole numbers in the range -227 to 227-1.
浮点数是实数 可以用小数点和科学计数法表示的数字(小写“e”表示 10 的幂)。例如,数字 5489 可以写成 5489、5.489e3、548.9e1 等。
Floating point numbers are real numbers that you can represent with decimal points and scientific notation (with lowercase "e" for the power of 10). For example, the number 5489 can be written 5489, 5.489e3, 548.9e1, and so on.
字符前面有一个问题标记,例如,
?a。Esc、
Newline和Tab分别缩写为\e、
\n和\t;其他控制字符用前缀 表示
\C-,因此(例如)Ca表示为
?\C-a。[ 3 ]
Characters are preceded by a
question mark, for example,
?a. Esc,
Newline, and Tab are abbreviated \e,
\n, and \t respectively; other
control characters are denoted with the prefix
\C-, so that (for example) C-a is denoted as
?\C-a.[3]
字符串被包围
双引号;字符串中的引号和反斜杠前面需要有反斜杠。例如,“ Jane said, \"See
Dick run.\"”是合法的字符串。字符串可以拆分为多行,无需任何特殊语法。结束引号之前的所有内容(包括所有换行符)都是字符串值的一部分。
Strings are surrounded by
double quotes;
quote marks and backslashes within strings need to be preceded by a
backslash. For example, "Jane said, \"See
Dick run.\"" is a legal string.
Strings can be split across multiple lines without any special
syntax. Everything until the closing quote, including all the line
breaks, is part of the string value.
布尔值用于t
true 和nilfalse,
尽管大多数时候,如果需要布尔值,则任何非nil值都被假定为 true。
nil正如我们将看到的,在各种情况下也用作空值或非值。
Booleans use t
for true and nil for false,
though
most of the time, if a Boolean value is expected, any
non-nil value is assumed to mean true.
nil is also used as a null or nonvalue in various
situations, as we will see.
符号是 Lisp 中事物的名称,例如例如,变量或函数的名称。有时,引用 某事物的名称而不是其值很重要,这是通过在名称前加上单引号 (') 来完成的。例如,第10章中描述的define-key函数使用命令的名称(作为符号)而不是命令本身。
Symbols are names of things in Lisp, for example, names of variables or functions. Sometimes it is important to refer to the name of something instead of its value, and this is done by preceding the name with a single quote ('). For example, the define-key function, described in Chapter 10, uses the name of the command (as a symbol) rather than the command itself.
将许多这些基本 Lisp 概念联系在一起的一个简单示例是函数setq。[ 4 ]正如您可能从前面的章节中了解到的,setq是一种为变量赋值的方法,如
A simple example that ties many of these basic Lisp concepts together is the function setq.[4] As you may have figured out from previous chapters, setq is a way of assigning values to variables, as in
(setq 自动保存间隔 800)
(setq auto-save-interval 800)
请注意,setq是一个函数,与其他语言不同,在其他语言中
使用=or等特殊语法:=进行赋值。
setq接受两个参数:变量名和值。在此示例中,变量auto-save-interval(自动保存之间的击键次数)设置为值800。
Notice that setq is a function,
unlike in other languages in which special syntax such as
= or := is used for assignment.
setq takes two arguments: a variable
name and a value. In this example, the variable auto-save-interval (the number of keystrokes
between auto-saves) is set to the value 800.
setq实际上可以用来给多个变量赋值,如
setq can actually be used to assign values to multiple variables, as in
(设置q )thisvar thisvaluethatvar thatvaluetheothervar theothervalue
(setqthisvar thisvaluethatvar thatvaluetheothervar theothervalue)
setq的返回值只是最后分配的值,在本例中为
theothervalue。正如我们将看到的,您可以通过其他方式设置变量的值,但setq是最广泛适用的。
The return value of setq is simply
the last value assigned, in this case
theothervalue. You can set the values of
variables in other ways, as we'll see, but setq is the most widely applicable.
现在是时候了
简单函数定义的示例。不带任何参数启动 Emacs;这会将您带入*scratch*
缓冲区,这是 Lisp 交互模式下的一个空缓冲区(请参阅第 9 章),以便您可以实际尝试此示例和后续示例。
Now it's time for
an
example of a simple function definition. Start Emacs without any
arguments; this puts you into the *scratch*
buffer, an empty buffer in Lisp interaction mode (see Chapter 9), so that you can actually try this and
subsequent examples.
然而,在我们讨论这个例子之前,有必要对 Lisp 语法做一些更多的评论。首先,您会注意到破折号 ( -) 用作“分隔”字符来分隔变量、函数等名称中的单词。这种做法只是一种广泛使用的 Lisp 编程约定;因此,_在 C 和 Ada 等语言中,破折号取代了下划线 ( )。一个更重要的问题与 Lisp 代码中的所有括号有关。 Lisp 是一种古老的语言,它是在人们对语言语法进行深入思考之前设计的(人们仍然认为可以使用本机处理器的二进制指令集以外的任何语言是令人惊奇的),因此它的语法并不完全适合程序员。然而,Lisp 大量使用列表——因此也大量使用括号——有其优点,我们将在本章末尾看到。
Before we get to the example, however, some more comments on Lisp
syntax are necessary. First, you will notice that the dash
(-) is used as a
"break" character to separate words
in names of variables, functions, and so on. This practice is simply
a widely used Lisp programming convention; thus the dash takes the
place of the underscore (_) in languages like C
and Ada. A more important issue has to do with all of the parentheses
in Lisp code. Lisp is an old language that was
designed before anyone gave much thought to language syntax (it was
still considered amazing that you could use any language other than
the native processor's binary instruction set), so
its syntax is not exactly programmer-friendly. Yet
Lisp's heavy use of lists—and thus its heavy
use of parentheses—has its advantages, as
we'll see toward the end of this chapter.
程序员面临的主要问题是如何保持所有括号的正确平衡。使这个问题更加复杂的是通常的编程约定,即在行尾放置多个右括号,而不是将每个右括号直接放在其匹配的左括号下方的更具可读性的技术。对此的最佳防御措施是 Emacs Lisp 模式为您提供的支持,特别是用于正确缩进的Tab键和 flash-matching-parenthesis 功能。
The main problem a programmer faces is how to keep all the parentheses balanced properly. Compounding this problem is the usual programming convention of putting multiple right parentheses at the end of a line, rather than the more readable technique of placing each right parenthesis directly below its matching left parenthesis. Your best defense against this is the support the Emacs Lisp modes give you, particularly the Tab key for proper indentation and the flash-matching-parenthesis feature.
现在我们已经准备好我们的示例函数了。假设您是一名学生或记者,需要跟踪您正在撰写的论文或故事的字数。 Emacs 没有内置的方法来计算缓冲区中的单词数,因此我们将编写一个 Lisp 函数来完成这项工作:
Now we're ready for our example function. Suppose you are a student or journalist who needs to keep track of the number of words in a paper or story you are writing. Emacs has no built-in way of counting the number of words in a buffer, so we'll write a Lisp function that does the job:
1(defun 计数字缓冲区 ( ) 2(让((数0)) 3(保存-游览 4(转到字符(点-分钟)) 5(同时(<(点)(点-最大)) 6(前向字 1) 7(setq 计数(1+ 计数))) 8(消息“缓冲区包含 %d 个单词。”计数))))
1 (defun count-words-buffer ( ) 2 (let ((count 0)) 3 (save-excursion 4 (goto-char (point-min)) 5 (while (< (point) (point-max)) 6 (forward-word 1) 7 (setq count (1+ count))) 8 (message "buffer contains %d words." count))))
让我们逐行浏览这个函数,看看它做了什么。 (当然,如果您在 Emacs 中尝试此操作,请不要输入行号。)
Let's go through this function line by line and see what it does. (Of course, if you are trying this in Emacs, don't type the line numbers in.)
第 1 行的 defun通过函数的名称和参数定义函数。请注意,defun本身就是一个函数,当调用时,定义一个新函数。 (defun以符号形式返回所定义函数的名称。)函数的参数显示为括号内的名称列表;在这种情况下,该函数没有参数。通过在参数前面加上关键字
&Optional可以将参数设为
可选。如果参数是可选的并且在调用函数时未提供,则假定其值是。nil
The defun on line 1 defines the
function by its name and arguments. Notice that defun is itself a function—one that,
when called, defines a new function. (defun returns the name of the function
defined, as a symbol.) The function's arguments
appear as a list of names inside parentheses; in this case, the
function has no arguments. Arguments can be made
optional by preceding them with the keyword
&optional. If an argument is
optional and not supplied when the function is called, its value is
assumed to be nil.
第 2 行包含一个let构造,其一般形式为:
Line 2 contains a let construct, whose general form is:
(让((var1 value1)(var2值2)...)statement-block)
(let ((var1 value1) (var2 value2) ... )statement-block)
let做的第一件事是定义变量var1、var2等,并将它们设置为初始值value1、
value2等。然后let执行语句块,该语句块是一系列函数调用或值的序列,就像函数体一样。
The first thing let does is define
the variables var1, var2, etc.,
and set them to the initial values value1,
value2, etc. Then let executes the statement
block, which is a sequence of function calls or values,
just like the body of a function.
将let视为做三件事是有用的:
It is useful to think of let as doing three things:
定义(或声明)变量列表
Defining (or declaring) a list of variables
将变量设置为初始值,就像使用setq一样
Setting the variables to initial values, as if with setq
创建一个变量已知的块;let块被称为 变量的范围
Creating a block in which the variables are known; the let block is known as the scope of the variables
如果使用let来定义变量,则可以稍后在let块中使用setq重置其值。此外,用let定义的变量 可以与全局变量同名;let块中该变量上的所有setq都作用于局部变量,使全局变量不受干扰。但是,对未使用let定义的变量进行setq会影响全局环境。建议尽可能避免使用全局变量,因为它们的名称可能与现有全局变量的名称冲突,因此您的更改可能会在以后产生意外且无法解释的副作用。
If a let is used to define a variable, its value can be reset later within the let block with setq. Furthermore, a variable defined with let can have the same name as a global variable; all setqs on that variable within the let block act on the local variable, leaving the global variable undisturbed. However, a setq on a variable that is not defined with a let affects the global environment. It is advisable to avoid using global variables as much as possible because their names might conflict with those of existing global variables and therefore your changes might have unexpected and inexplicable side effects later on.
因此,在我们的示例函数中,我们使用let定义局部变量count并将其初始化为 0。正如我们将看到的,该变量用作循环计数器。
So, in our example function, we use let to define the local variable count and initialize it to 0. As we will see, this variable is used as a loop counter.
第 3 行到第 8 行是let块中的语句。第一个调用内置的 Emacs 函数save-excursion,这是一种礼貌的方式。该函数将在缓冲区周围移动光标,因此我们不想仅仅因为用户要求字数统计而将他们跳转到文件中的陌生位置,从而使用户迷失方向。调用save-excursion 告诉 Emacs 记住函数开头的光标位置,并在执行函数体中的任何语句后返回到那里。请注意save-excursion如何为我们提供类似于let 的功能;您可以将其视为使光标位置本身成为局部变量的一种方法。
Lines 3 through 8 are the statements within the let block. The first of these calls the built-in Emacs function save-excursion, which is a way of being polite. The function is going to move the cursor around the buffer, so we don't want to disorient the user by jumping them to a strange place in their file just because they asked for a word count. Calling save-excursion tells Emacs to remember the location of cursor at the beginning of the function, and go back there after executing any statements in its body. Notice how save-excursion is providing us with capability similar to let; you can think of it as a way of making the cursor location itself a local variable.
第 4 行调用goto-char。goto-char的参数是对内置函数point-min的(嵌套)函数调用。正如我们之前提到的, point是 Emacs 对光标位置的内部名称,在本章的其余部分中我们将把光标称为 point。 point-min返回当前缓冲区中第一个字符位置的值,几乎总是 1;然后,使用值 1 调用goto-char ,其效果是将指针移动到缓冲区的开头。
Line 4 calls goto-char. The argument to goto-char is a (nested) function call to the built-in function point-min. As we have mentioned before, point is Emacs's internal name for the position of the cursor, and we'll refer to the cursor as point throughout the remainder of this chapter. point-min returns the value of the first character position in the current buffer, which is almost always 1; then, goto-char is called with the value 1, which has the effect of moving point to the beginning of the buffer.
下一行设置一个while循环; Java 和 Perl 有类似的构造。 while结构具有一般形式
The next line sets up a while loop; Java and Perl have a similar construct. The while construct has the general form
(尽管)conditionstatement-block
(whileconditionstatement-block)
与let和save-excursion类似,while设置另一个语句块。
条件是一个值(原子、变量或返回值的函数)。该值经过测试;如果是nil,则认为条件为假,并且while循环终止。如果该值不是nil,则条件被视为 true,执行语句块,再次测试条件,然后重复该过程。
Like let and save-excursion, while sets up another statement block.
condition is a value (an atom, a
variable, or a function returning a value). This value is tested; if
it is nil, the condition is considered to be
false, and the while loop
terminates. If the value is other than nil, the
condition is considered to be true, the statement block gets
executed, the condition is tested again, and the process repeats.
当然,也可以写一个无限循环。如果您编写一个带有while循环的 Lisp 函数并尝试运行它,而您的 Emacs 会话挂起,那么您很可能犯了这个非常常见的错误;只需输入Cg即可中止它。
Of course, it is possible to write an infinite loop. If you write a Lisp function with a while loop and try running it, and your Emacs session hangs, chances are that you have made this all-too-common mistake; just type C-g to abort it.
在我们的示例函数中,条件是 function
<,它是一个带有两个参数的小于函数,类似于 Java 或 Perl 中的 < 运算符。第一个参数是另一个函数,返回 point 的当前字符位置;第二个参数返回缓冲区中的最大字符位置,即缓冲区的长度。该函数<(和其他关系函数)返回一个布尔值,t或
nil。
In our sample function, the condition is the function
<, which is a less-than function with two
arguments, analogous to the < operator in Java or Perl. The first
argument is another function that returns the current character
position of point; the second argument returns the maximum character
position in the buffer, that is, the length of the buffer. The
function < (and other relational functions)
return a Boolean value, t or
nil.
循环的语句块由两条语句组成。第 6 行将点向前移动一个字(即,就像您键入了Mf一样)。第 7 行将循环计数器加 1;该函数1+是 的简写(+ 1 variable-name)。请注意,第 7 行的第三个右括号与while前面的左括号匹配
。因此,while循环使 Emacs 在对单词进行计数的同时一次遍历当前缓冲区一个单词。
The loop's statement block consists of two
statements. Line 6 moves point forward one word (i.e., as if you had
typed M-f). Line 7 increments the
loop counter by 1; the function 1+ is shorthand
for (+ 1 variable-name). Notice that the third
right parenthesis on line 7 matches the left parenthesis preceding
while. So, the while loop causes Emacs to go through the
current buffer a word at a time while counting the words.
函数中的最后一条语句使用内置函数
message在迷你缓冲区中打印一条消息,说明缓冲区包含多少个单词。C 程序员会熟悉消息函数的形式
。 message的第一个参数是格式字符串,其中包含 形式的文本和特殊格式指令
%
x,其中
x是几个可能的字母之一。对于这些指令中的每一个,按照它们在格式字符串中出现的顺序,message读取下一个参数并尝试根据百分号后面的字母来解释它。
表 11-1列出了格式字符串中字母的含义。
The final statement in the function uses the built-in function
message to print a message in the
minibuffer saying how many words the buffer contains. The form of the
message function will be familiar to
C programmers. The first argument to message is a format string, which contains
text and special formatting instructions of the form
%
x, where
x is one of a few possible letters. For
each of these instructions, in the order in which they appear in the
format string, message reads the next argument and
tries to interpret it according to the letter after the percent sign.
Table 11-1 lists meanings for the letters in the
format string.
表 11-1。消息格式字符串
Table 11-1. Message format strings
|
格式化字符串 Format string |
意义 Meaning |
|---|---|
|
|
字符串或符号 String or symbol |
|
|
特点 Character |
|
|
整数 Integer |
|
|
科学记数法中的浮点数 Floating point in scientific notation |
|
|
小数点表示法中的浮点 Floating point in decimal-point notation |
|
|
无论哪种格式的浮点都会产生最短的字符串 Floating point in whichever format yields the shortest string |
例如:
For example:
(消息“\”%s\”是字符串,%d是数字,%c是字符”
“你好”142?q)(message "\"%s\" is a string, %d is a number, and %c is a character"
"hi there" 142 ?q)导致消息:
causes the message:
“hithere”是一个字符串,142是一个数字,q是一个字符
"hi there" is a string, 142 is a number, and q is a character
出现在迷你缓冲区中。这类似于 C 代码:
to appear in the minibuffer. This is analogous to the C code:
printf("\"%s\"是字符串,%d是数字,%c是字符\n",
“你好”,142,“q”);printf ("\"%s\" is a string, %d is a number, and %c is a character\n",
"hi there", 142, 'q');浮点格式字符有点复杂。除非您另有说明,否则它们会假定一定数量的有效数字。例如,以下内容:
The floating-point-format characters are a bit more complicated. They assume a certain number of significant digits unless you tell them otherwise. For example, the following:
(消息“这本书是用 %f 印刷的,也称为 %e。”2004 2004)
(message "This book was printed in %f, also known as %e." 2004 2004)
产生这个:
yields this:
本书印刷于2004.000000,也称为2.004000e+03。
This book was printed in 2004.000000, also known as 2.004000e+03.
%但是您可以通过在和之间插入句点和所需的位数来控制小数点后的位数
、e、
f或g。例如,这个:
But you can control the number of digits after the decimal point by
inserting a period and the number of digits desired between the
% and
the e,
f, or g. For example, this:
(消息“本书以 %.3e 印刷,也称为 %.0f。”2004 2004)
(message "This book was printed in %.3e, also known as %.0f." 2004 2004)
在迷你缓冲区中打印:
prints in the minibuffer:
这本书印刷于2.004e+03,也称为2004年。
This book was printed in 2.004e+03, also known as 2004.
字数缓冲区函数 我们刚刚完成了工作,但它仍然不如您日常使用的 Emacs 命令那么方便。如果你已经输入了,请自己尝试一下。首先,您需要让 Emacs 计算您输入的行,从而实际定义函数。为此,请将光标移动到函数中最后一个右括号之后,然后键入Cj (或Linefeed)(Lisp 交互模式中的“evaluate”键)来告诉 Emacs 执行函数定义。您应该看到函数的名称再次出现在缓冲区中;defun函数的返回值是已经定义的符号。 (如果您收到错误消息,请仔细检查您的函数是否与示例完全相同,并且您没有输入行号,然后重试。)
The count-words-buffer function that we've just finished works, but it still isn't as convenient to use as the Emacs commands you work with daily. If you have typed it in, try it yourself. First you need to get Emacs to evaluate the lines you typed in, thereby actually defining the function. To do this, move your cursor to just after the last closing parenthesis in the function and type C-j (or Linefeed)—the "evaluate" key in Lisp interaction mode—to tell Emacs to perform the function definition. You should see the name of the function appear again in the buffer; the return value of the defun function is the symbol that has been defined. (If instead you get an error message, double check that your function looks exactly like the example and that you haven't typed in the line numbers, and try again.)
定义函数后,您可以通过在 Lisp 交互窗口中在其自己的行上键入(count-words-buffer)来执行它,并在右括号后再次键入Cj 。
Once the function is defined, you can execute it by typing (count-words-buffer) on its own line in your Lisp interaction window, and once again typing C-j after the closing parenthesis.
现在您可以从 Lisp 交互窗口正确执行该函数,请尝试使用Mx执行该函数,就像使用任何其他 Emacs 命令一样。尝试输入Mx count-words-buffer Enter:您将收到错误消息[No match]。 (您可以输入Cg来取消这次失败的尝试。)您收到此错误消息是因为您需要向 Emacs“注册”一个函数以使其可供交互使用。执行此操作的函数是
Interactive,其形式为:
Now that you can execute the function correctly from a Lisp
interaction window, try executing the function with M-x, as with any other Emacs command. Try
typing M-x count-words-buffer Enter:
you will get the error message [No match]. (You
can type C-g to cancel this failed
attempt.) You get this error message because you need to
"register" a function with Emacs to
make it available for interactive use. The function to do this is
interactive, which has the form:
(交互式“提示字符串”)
(interactive "prompt-string")
该语句应该是函数中的第一个语句,即位于包含 defun和 文档字符串(我们将很快介绍)的行之后。使用 交互式会使 Emacs 将函数注册为命令并提示用户输入defun语句中声明的参数。提示字符串是可选的。
This statement should be the first in a function, that is, right after the line containing the defun and the documentation string (which we will cover shortly). Using interactive causes Emacs to register the function as a command and to prompt the user for the arguments declared in the defun statement. The prompt string is optional.
提示字符串具有特殊格式:对于要提示用户输入的每个参数,您提供提示字符串的一部分。这些部分由换行符 ( ) 分隔\n。每个的第一个字母
部分是您想要的参数类型的代码。有很多选择;最常用的列于表11-2。
The prompt string has a special format: for each argument you want to
prompt the user for, you provide a section of prompt string. The
sections are separated by newlines (\n). The first
letter of each
section is a code for
the type of argument you want. There are many choices; the most
commonly used are listed in Table 11-2.
表 11-2。交互函数的参数代码
Table 11-2. Argument codes for interactive functions
|
代码 Code |
系统会提示用户: User is prompted for: |
|---|---|
|
|
现有缓冲区的名称 Name of an existing buffer |
|
|
事件(鼠标操作或功能键按下) Event (mouse action or function key press) |
|
|
现有文件的名称 Name of an existing file |
|
|
数量(整数) Number (integer) |
|
|
细绳 String |
|
其中大多数都有大写变体 Most of these have uppercase variations | |
|
|
可能不存在的缓冲区名称 Name of a buffer that may not exist |
|
|
可能不存在的文件名 Name of a file that may not exist |
|
|
数字,除非使用前缀参数调用命令,在这种情况下使用前缀参数并跳过此提示 Number, unless command is invoked with a prefix argument, in which case use the prefix argument and skip this prompt |
|
|
象征 Symbol |
使用b和f选项,如果给定的缓冲区或文件尚不存在,Emacs 会发出错误信号。另一个有用的交互选项 是r,我们稍后会看到。还有许多其他选项字母;有关详细信息,请参阅交互式函数的文档 。每个部分的其余部分是出现在迷你缓冲区中的实际提示。
With the b and f options, Emacs signals an error if the buffer or file given does not already exist. Another useful option to interactive is r, which we will see later. There are many other option letters; consult the documentation for function interactive for the details. The rest of each section is the actual prompt that appears in the minibuffer.
使用交互方式填充函数参数的方式有些复杂,最好通过示例来解释。一个简单的例子是goto-percent函数,我们很快就会看到它。它包含以下语句
The way interactive is used to fill in function arguments is somewhat complicated and best explained through an example. A simple example is in the function goto-percent, which we will see shortly. It contains the statement
(交互式“nPercent:”)
(interactive "nPercent: ")
n提示字符串中的 告诉 Emacs 提示输入一个整数;字符串Percent: 出现在迷你缓冲区中。
The n in the prompt string tells Emacs to prompt
for an integer; the string Percent: appears in the
minibuffer.
作为一个稍微复杂一点的例子,假设我们想要编写我们自己的替换字符串命令版本。以下是我们如何进行提示:
As a slightly more complicated example, let's say we want to write our own version of the replace-string command. Here's how we would do the prompting:
(defun 替换字符串(从 到) (交互式“s替换字符串:\ns将字符串 %s 替换为:”) ...)
(defun replace-string (from to) (interactive "sReplace string: \nsReplace string %s with: ") ...)
提示字符串由两部分组成:sReplace
string: 和sReplace string
%s
with:,以换行符分隔。每个中的首字母
s表示需要一个字符串; the
%s是一个格式化运算符(如前面的
消息函数中所示),Emacs 将其替换为用户对第一个提示的响应。在提示中应用格式化运算符时,就好像
已使用迄今为止读取的所有响应的列表调用消息,因此第一个格式化运算符将应用于第一个响应,依此类推。
The prompt string consists of two sections, sReplace
string: and sReplace string
%s
with:, separated by a Newline. The initial
s in each means that a string is expected; the
%s is a formatting operator (as in the previous
message function) that Emacs
replaces with the user's response to the first
prompt. When applying formatting operators in a prompt, it is as if
message has been called with a list
of all responses read so far, so the first formatting operator is
applied to the first response, and so on.
当调用此命令时,首先提示符Replace
string:出现在迷你缓冲区中。假设用户键入
fred响应。用户按
EnterReplace
fred with后,出现提示符:。用户键入替换字符串并再次按Enter 键。
When this command is invoked, first the prompt Replace
string: appears in the minibuffer. Assume the user types
fred in response. After the user presses
Enter, the prompt Replace
fred with: appears. The user types the replacement string
and presses Enter again.
用户输入的两个字符串用作函数参数from和to的值(按该顺序),并且命令运行直至完成。因此,交互式 按照提示字符串各部分的顺序向函数的参数提供值。
The two strings the user types are used as values of the function arguments from and to (in that order), and the command runs to completion. Thus, interactive supplies values to the function's arguments in the order of the sections of the prompt string.
Interactive的使用并不排除从其他 Lisp 代码中调用该函数;在这种情况下,调用函数需要为所有参数提供值。例如,如果我们有兴趣从另一个 Lisp 函数调用我们的替换字符串版本,该函数需要将文件中所有出现的“Bill”替换为“Deb”,我们将使用
The use of interactive does not preclude calling the function from other Lisp code; in this case, the calling function needs to supply values for all arguments. For example, if we were interested in calling our version of replace-string from another Lisp function that needs to replace all occurrences of "Bill" with "Deb" in a file, we would use
(替换字符串“Bill”“Deb”)
(replace-string "Bill" "Deb")
在这种情况下,函数没有被交互调用,因此 交互语句没有效果;参数from设置为“Bill”,to设置为“Deb”。
The function is not being called interactively in this case, so the interactive statement has no effect; the argument from is set to "Bill," and to is set to "Deb."
回到我们的count-words-buffer命令:它没有参数,因此它的交互式 命令不需要提示字符串。我们要对命令进行的最后修改是添加文档字符串(或简称doc 字符串),该字符串由在线帮助工具(如描述函数(Ch f))显示。 Doc 字符串是普通的 Lisp 字符串;它们是可选的,并且可以是任意多行,但按照惯例,第一行是一个简洁、完整的句子,总结了命令的功能。请记住,字符串内的任何双引号前面都需要有反斜杠。
Getting back to our count-words-buffer command: it has no arguments, so its interactive command does not need a prompt string. The final modification we want to make to our command is to add a documentation string (or doc string for short), which is shown by online help facilities such as describe-function (C-h f). Doc strings are normal Lisp strings; they are optional and can be arbitrarily many lines long, although, by convention, the first line is a terse, complete sentence summarizing the command's functionality. Remember that any double quotes inside a string need to be preceded by backslashes.
With all of the fixes taken into account, the complete function looks like this:
(defun 计数字数缓冲区 ( )
"统计当前缓冲区中的字数;
在迷你缓冲区中打印一条带有结果的消息。”
(交互的)
(保存游览
(让((数0))
(goto-char (点-分钟))
(而(<(点)(点-最大))
(前向字1)
(setq 计数(1+ 计数)))
(消息“缓冲区包含 %d 个单词。”计数))))(defun count-words-buffer ( )
"Count the number of words in the current buffer;
print a message in the minibuffer with the result."
(interactive)
(save-excursion
(let ((count 0))
(goto-char (point-min))
(while (< (point) (point-max))
(forward-word 1)
(setq count (1+ count)))
(message "buffer contains %d words." count))))[ 1 ]我们推荐Patrick Henry Winston 和 Berthold Klaus Paul Horn (Addison Wesley) 所著的Lisp 。
[1] We recommend Lisp by Patrick Henry Winston and Berthold Klaus Paul Horn (Addison Wesley).
[ 2 ]经验丰富的 Lisp 程序员应该注意到,Emacs Lisp 与 MacLisp 最相似,只是添加了一些 Common Lisp 功能。通过加载该包可以获得更完整的 Common Lisp 模拟
cl(参见附录 B)。
[2] Experienced Lisp programmers should note that Emacs Lisp most
closely resembles MacLisp, with a few Common Lisp features added.
More complete Common Lisp emulation can be had by loading the package
cl (see Appendix B).
现在您已经了解了如何 编写一个工作命令后,我们将讨论 Lisp 的原始函数。这些是您构建函数的构建块。如上所述,Lisp 使用其他语言使用运算符的函数,即算术、比较和逻辑。表 11-3显示了一些与这些运算符等效的 Lisp 原语函数。
Now that you've seen how to write a working command, we'll discuss Lisp's primitive functions. These are the building blocks from which you'll build your functions. As mentioned above, Lisp uses functions where other languages would use operators, that is, for arithmetic, comparison, and logic. Table 11-3 shows some Lisp primitive functions that are equivalent to these operators.
表 11-3。 Lisp 原始函数
Table 11-3. Lisp primitive functions
|
算术 Arithmetic |
|
|
| |
|
| |
|
| |
|
| |
|
比较 Comparison |
|
|
| |
|
| |
|
| |
|
逻辑 Logic |
|
1+除、
1-和之外的所有算术函数%都可以采用任意多个参数,就像and和 一样
or。仅当至少一个参数是浮点数时,算术函数才会返回浮点值,例如,(/ 7.0 4)返回 1.75,然后
(/ 7 4)返回 1。请注意,整数除法会截断余数。
All the arithmetic functions except 1+,
1-, and % can take arbitrarily
many arguments, as can and and
or. An arithmetic function returns floating point
values only if at least one argument is a floating point number, so
for example, (/ 7.0 4) returns 1.75, and
(/ 7 4) returns 1. Notice that integer division
truncates the remainder.
对所有事情都使用函数可能看起来效率低下或语法丑陋。然而,Lisp 的主要优点之一是该语言的核心很小并且易于高效解释。此外,如果您有支持工具(例如 Emacs 的 Lisp 模式)来帮助您,那么语法并不是什么大问题。
It may seem inefficient or syntactically ugly to use functions for everything. However, one of the main merits of Lisp is that the core of the language is small and easy to interpret efficiently. In addition, the syntax is not as much of a problem if you have support tools such as Emacs's Lisp modes to help you.
我们已经看到,一个 可以使用let函数定义语句块。我们还看到while和save-excursion包含语句块。其他重要的构造也定义了语句块:progn和其他形式的let。
We have seen that a statement block can be defined using the let function. We also saw that while and save-excursion include statement blocks. Other important constructs also define statement blocks: progn and other forms of let.
progn是最基本的形式:
progn, the most basic, has the form:
(程序
statement-block) (progn
statement-block)
progn是一种使语句块看起来像单个语句的简单方法,有点像 Java 的大括号或Pascal 的beginand
。 prognend返回的值是块中最后一条语句返回的值。 progn对于像if(参见下面的讨论)
这样的控制结构特别有用,与while不同,它不包含语句块。
progn is a simple way of making a
block of statements look like a single one, somewhat like the curly
braces of Java or the begin and
end of Pascal. The value returned by progn is the value returned by the last
statement in the block. progn is
especially useful with control structures like if (see the following discussion) that, unlike
while, do not include statement
blocks.
let函数还有其他形式。最简单的是:
The let function has other forms as well. The simplest is:
(让 (..。) )var1 var2statement-block
(let (var1 var2...)statement-block)
在这种情况下,不是成对的列表
,而是简单的变量名称列表。与 let 的其他形式一样,它们成为可在语句块中访问的局部变量。但是,它们不是将它们初始化为给定值,而是全部初始化为
.实际上,您可以在同一个let语句中混合使用这两种形式,例如:(
var
value
)nil
In this case, instead of a list of
(
var
value
) pairs, there is simply a list
of variable names. As with the other form of let, these become local
variables accessible in the statement block. However, instead of
initializing them to given values, they are all just initialized to
nil. You can actually mix both forms within
the same let statement, for example:
(让(var1(var2值2)var3...)statement-block)
(let (var1(var2 value2) var3 ...)statement-block)
在let的形式中,我们首先看到,局部变量的初始值可以是函数调用(记住所有函数都返回值)。所有此类函数都会在将任何值分配给变量之前进行评估。但是,在某些情况下,您可能希望某些局部变量的值可用于计算其他局部变量的值。这就是 let* ( let的最终版本)发挥作用的地方。let *按顺序逐步执行其赋值操作,为每个局部变量分配一个值,然后再继续进行下一个局部变量。
In the form of let we saw first, the initial values for the local variables can be function calls (remember that all functions return values). All such functions are evaluated before any values are assigned to variables. However, there may be cases in which you want the values of some local variables to be available for computing the values of others. This is where let*, the final version of let, comes in. let* steps through its assignments in order, assigning each local variable a value before moving on to the next.
例如,假设我们要编写一个函数 goto-percent,它允许您转到当前缓冲区中的某个位置,以缓冲区中文本的百分比表示。这是编写此函数的一种方法:
For example, let's say we want to write a function goto-percent that allows you to go to a place in the current buffer expressed as a percentage of the text in the buffer. Here is one way to write this function:
(defun goto-百分比 (pct)
(交互式“nGoto 百分比:”)
(让* ((大小(点-最大))
(charpos (/ (* 大小 pct) 100)))
(goto-char charpos)))(defun goto-percent (pct)
(interactive "nGoto percent: ")
(let* ((size (point-max))
(charpos (/ (* size pct) 100)))
(goto-char charpos)))正如我们之前看到的,交互式 函数用于提示用户输入参数值。在这种情况下,它会提示输入参数pct的整数值。然后,let*函数将size初始化为缓冲区大小(以字符为单位),然后使用该值计算字符位置charpos,即缓冲区大小的pct (百分比)。最后,调用goto-char 会使 point 移动到当前窗口中的该字符位置。
As we saw earlier, the interactive function is used to prompt users for values of arguments. In this case, it prompts for the integer value of the argument pct. Then the let* function initializes size to the size of the buffer in characters, then uses that value to compute the character position charpos that is pct (percent) of the buffer's size. Finally, the call of goto-char causes point to be moved to that character position in the current window.
需要注意的重要一点是,如果我们使用let而不是let* ,则在计算charpos的值时, size的值将不可用。let*也可以在该格式中使用
,就像let一样,但这样做没有任何意义。(
var1 var2
...
)
The important thing to notice is that if we had used let instead of let*, the value of size would not be available when computing the
value of charpos. let* can also be used in the
(
var1 var2
...
) format, just like let, but there wouldn't be
any point in doing so.
我们还应该注意到,编写goto-percent 的更有效方法是:
We should also note that a more efficient way to write goto-percent is this:
(defun goto-百分比 (pct) (交互式“nPercent:”) (转到字符(/(* pct(最大点))100)))
(defun goto-percent (pct) (interactive "nPercent: ") (goto-char (/ (* pct (point-max)) 100)))
我们已经看到while 函数 就像其他语言中的类似语句一样充当控制结构。 Lisp 中还有另外两个重要的控制结构:if和cond。
We already saw that the while function acts as a control structure like similar statements in other languages. There are two other important control structures in Lisp: if and cond.
if函数的形式为:
The if function has the form:
(如果)conditiontrue-casefalse-block
(ifconditiontrue-casefalse-block)
在这里,评估条件;如果它不为零,则true-case进行评估;如果nil,
false-block则进行评估。请注意,
true-case是单个语句,而
false-block是语句块;
false-block是可选的。
Here, the condition is evaluated; if it is non-nil, true-case is
evaluated; if nil,
false-block is evaluated. Note that
true-case is a single statement whereas
false-block is a statement block;
false-block is optional.
举个例子,假设我们正在编写一个函数,该函数对缓冲区执行一系列复杂的编辑,然后报告它所做的更改数量。我们是完美主义者,因此我们希望状态报告能够适当地多元化,也就是说“进行了 53 项更改”或“进行了 1 项更改”。这是一种常见的编程需求,我们决定编写一个通用函数来完成它,以便我们也可以在其他项目中使用它。
As an example, let's suppose we're writing a function that performs some complicated series of edits to a buffer and then reports how many changes it made. We're perfectionists, so we want the status report to be properly pluralized, that is to say "made 53 changes" or "made 1 change." This is a common enough programming need that we decide to write a general-purpose function to do it so that we can use it in other projects too.
该函数有两个参数:要复数的单词(如果需要)和要显示的计数(决定是否需要)。
The function takes two arguments: the word to be pluralized (if necessary) and the count to be displayed (which determines whether it's necessary).
(defun 复数(字数)
(如果(= 计数 1)
单词
(连接词“s”)))(defun pluralize (word count)
(if (= count 1)
word
(concat word "s")))if子句中的条件测试count是否等于 1。如果是,则执行第一个语句。请记住, if函数的“true”部分只是一个语句,因此 如果我们想做不止一件事,则需要progn来创建一个语句块。在这种情况下,我们有相反的极端;我们的“真实”部分是一个变量, word。虽然这看起来很奇怪,但它实际上是一个非常常见的 Lisp 习惯用法,值得习惯。当条件块为真时,对word的值进行求值,该值成为整个if语句的值。因为这是我们函数中的最后一个语句,所以它是pluralize返回的值。请注意,这正是count为 1 时我们想要的结果: word的值原封不动地返回。
The condition in the if clause tests to see if count is equal to 1. If so, the first statement gets executed. Remember that the "true" part of the if function is only one statement, so progn would be necessary to make a statement block if we wanted to do more than one thing. In this case, we have the opposite extreme; our "true" part is a single variable, word. Although this looks strange, it is actually a very common Lisp idiom and worth getting used to. When the condition block is true, the value of word is evaluated, and this value becomes the value of the entire if statement. Because that's the last statement in our function, it is the value returned by pluralize. Note that this is exactly the result we want when count is 1: the value of word is returned unchanged.
当条件为 false 时(也就是说,当count的值不为 1 时),将计算if语句的剩余部分。这会导致调用内置concat函数,该函数将其所有参数连接成一个细绳。在本例中,它会在我们传入的单词末尾添加一个“s”。同样,此连接的结果将成为if语句的结果和pluralize函数的结果。
The remaining portion of the if statement is evaluated when the condition is false, which is to say, when count has a value other than 1. This results in a call to the built-in concat function, which concatenates all its arguments into a single string. In this case it adds an "s" at the end of the word we've passed in. Again, the result of this concatenation becomes the result of the if statement and the result of our pluralize function.
如果您输入并尝试一下,您将看到如下结果:
If you type it in and try it out, you'll see results like this:
(pluralize "goat" 5)“山羊”(pluralize "change" 1)“改变”
(pluralize "goat" 5)"goats"(pluralize "change" 1)"change"
当然,这个功能很容易被绊倒。您可能已经尝试过这样的事情:
Of course, this function can be tripped up easily enough. You may have tried something like this already:
(pluralize "mouse" 5)
“老鼠” (pluralize "mouse" 5)
"mouses"为了解决这个问题,我们需要能够告诉函数对棘手的单词使用替代的复数形式。但如果简单的案例能像现在这样简单就好了。这是使用可选参数的好机会。如有必要,我们提供复数形式供使用;如果我们不提供一个,该函数的行为就像它在第一个版本中一样。以下是我们实现这一目标的方法:
To fix this, we'd need to be able to tell the function to use an alternate plural form for tricky words. But it would be nice if the simple cases could remain as simple as they are now. This is a good opportunity to use an optional parameter. If necessary, we supply the plural form to use; if we don't supply one, the function acts as it did in its first incarnation. Here's how we'd achieve that:
(defun 复数(字数和可选复数)
(如果(= 计数 1)
单词
(如果(空复数)
(连接词“s”)
复数)))(defun pluralize (word count &optional plural)
(if (= count 1)
word
(if (null plural)
(concat word "s")
plural)))我们代码的“else”部分变成了另一个if语句。它使用null函数来检查我们是否获得了复数参数。如果省略plural,则其值为nil,并且如果参数为nil ,则null函数返回t。所以这个逻辑是“如果 b丢失,只需在word中添加s ;否则返回 我们给出的特殊复数值。”
The "else" part of our code has become another if statement. It uses the null function to check whether we were given the plural parameter or not. If plural was omitted, it has the value nil and the null function returns t if its argument is nil. So this logic reads "if b was missing, just add an s to word; otherwise return the special plural value we were given."
这给了我们这样的结果:
This gives us results like this:
(pluralize "mouse" 5)“老鼠”(pluralize "mouse" 5 "mice")“老鼠”(pluralize "mouse" 1 "mice")“老鼠”
(pluralize "mouse" 5)"mouses"(pluralize "mouse" 5 "mice")"mice"(pluralize "mouse" 1 "mice")"mouse"
更通用的条件控制结构是cond函数,其形式如下:
A more general conditional control structure is the cond function, which has the following form:
(条件
( )condition1
statement-block1
( )
... .)condition2
statement-block2 (cond
(condition1
statement-block1)
(condition2
statement-block2)
...)Java 和 Perl 程序员可以将其视为
if then else if then else if的序列。 。 。 ,或作为一种广义的 switch 语句。条件按顺序求值,当其中一个条件求值为 non- 时nil,执行相应的语句块; cond函数终止并返回该语句块中的最后一个值。[ 5 ]
Java and Perl programmers can think of this as a sequence of
if then else if then else if . . . , or as a
kind of generalized switch statement. The conditions are evaluated in
order, and when one of them evaluates to non-nil,
the corresponding statement block is executed; the cond function terminates and returns the last
value in that statement block.[5]
现在我们可以使用cond来给我们假设的状态报告者带来更亲切的感觉,因为它已经很好地实现了复数化。我们可以根据需要显示“no”、“one ” 、 “ two ”或“many”,而不是报告更改数量的实际数值。 我们将再次编写一个通用函数来执行此操作:
We can use cond to give a more folksy feel to our hypothetical status reporter now that it's pluralizing nicely. Instead of reporting an actual numeric value for the number of changes, we could have it say no, one, two, or many as appropriate. Again we'll write a general function to do this:
(defun 有多少(计数)
(cond ((归零计数)“否”)
((=数1)“一”)
((=数2)“二”)
(t“很多”)))(defun how-many (count)
(cond ((zerop count) "no")
((= count 1) "one")
((= count 2) "two")
(t "many")))第一个条件
表达式引入了一个新的原始 Lisp 函数,zerop。它检查其参数是否为零,t
如果为零则返回 (true)。因此,当count为零时,cond语句采用第一个分支,并且我们的函数返回值no。这个奇怪的函数名称需要一些解释。它的发音是“zero-pee”,是“zero predicate”的缩写。在 Lisp 发展而来的数理逻辑领域中,谓词是一个根据其参数的某些属性返回 true 或 false 的函数。 Lisp 有多种类似的谓词函数,其名称在结构上也相关。当你遇到下一个时,你就会明白。 (当然,您现在可能期望我们在上一个示例中引入的null函数被称为“ nilp ”。没有人是完全一致的。)
The first conditional
expression introduces a new
primitive Lisp function, zerop. It
checks whether its argument is zero, and returns t
(true) when it is. So when count is
zero, the cond statement takes this
first branch, and our function returns the value no. This strange function name bears a little
explanation. It is pronounced
"zero-pee" and is short for
"zero predicate." In the realm of
mathematical logic from which Lisp evolved, a predicate is a function
that returns true or false based on some attribute of its argument.
Lisp has a wide variety of similar predicate functions, with
structurally related names. When you run into the next one,
you'll understand it. (Of course, you might now
expect the null function we
introduced in the previous example to be called
"nilp" instead.
Nobody's perfectly consistent.)
cond语句中的接下来两个条件表达式检查count是 1 还是 2,并使其根据需要返回“一”或“二”。我们本可以使用相同的结构编写第一个,但这样我们就错过了一个离题讨论 Lisp 琐事的机会!
The next two conditional expressions in the cond statement check if count is 1 or 2 and cause it to return "one" or "two" as appropriate. We could have written the first one using the same structure, but then we'd have missed out on an opportunity for a digression into Lisp trivia!
最后一个条件表达式只是原子t (true),这意味着只要前面的所有表达式都失败,就会执行其主体。它返回值 Many。执行这个函数会得到如下结果:
The last conditional expression is simply the atom t (true), which means its body is executed whenever all the preceding expressions failed. It returns the value many. Executing this function gives us results like these:
(how-many 1)“一”(how-many 0)“不”(how-many 3)“许多”
(how-many 1)"one"(how-many 0)"no"(how-many 3)"many"
将这两个辅助函数组合成一个机制来报告我们奇特命令的更改计数很容易。
Combining these two helper functions into a mechanism to report the change count for our fancy command is easy.
(defun 报告更改计数(计数) (消息“已完成 %s %s。”(多少计数)(复数“更改”计数)))
(defun report-change-count (count) (message "Made %s %s." (how-many count) (pluralize "change" count)))
我们得到如下结果:
We get results like these:
(report-change-count 0)“没有做任何改变。”(report-change-count 1)“做了一处改变。”(report-change-count 1329)“做了很多改变。”
(report-change-count 0)"Made no changes."(report-change-count 1)"Made one change."(report-change-count 1329)"Made many changes."
[ 5 ]语句块实际上是可选的;一些程序员喜欢省略最后的语句块,将最后的“条件”保留为“否则”子句,如果前面的所有条件都计算为 则要执行
nil。如果省略语句块,则返回的值cond只是条件的值。
[5] Statement blocks are
actually optional; some programmers like to omit the final statement
block, leaving the final
"condition" as an
"otherwise" clause to be executed
if all of the preceding conditions evaluate to
nil. If the statement block is omitted, the value
returned by cond is simply the value of the
condition.
Emacs 的许多功能 存在并且您可能编写的内容涉及搜索和操作缓冲区中的文本。这些函数在专用模式中特别有用,例如第 9 章中描述的编程语言模式。许多内置 Emacs 函数与字符串和缓冲区中的文本相关;最有趣的是利用了 Emacs 的正则表达式功能,我们在第 3 章中介绍了该功能。
Many of the Emacs functions that exist and that you may write involve searching and manipulating the text in a buffer. Such functions are particularly useful in specialized modes, like the programming language modes described in Chapter 9. Many built-in Emacs functions relate to text in strings and buffers; the most interesting ones take advantage of Emacs's regular expression facility, which we introduced in Chapter 3.
我们首先描述与不使用正则表达式的缓冲区和字符串相关的基本函数。之后,我们将比第 3 章更深入地讨论正则表达式,重点关注对 Lisp 程序员最有用的功能,并描述 Emacs 提供的可用于处理正则表达式的函数。
We first describe the basic functions relating to buffers and strings that don't use regular expressions. Afterwards, we discuss regular expressions in more depth than was the case in Chapter 3, concentrating on the features that are most useful to Lisp programmers, and we describe the functions that Emacs makes available for dealing with regular expressions.
表 11-4显示了一些基本的 与缓冲区、文本和字符串相关的 Emacs 函数仅对 Lisp 程序员有用,因此不受击键限制。我们已经在count-words-buffer示例中看到了其中的几个 。请注意,其中一些是谓词,它们的名称反映了这一点。
Table 11-4 shows some basic Emacs functions relating to buffers, text, and strings that are only useful to Lisp programmers and thus aren't bound to keystrokes. We already saw a couple of them in the count-words-buffer example. Notice that some of these are predicates, and their names reflect this.
表 11-4。缓冲区和文本函数
Table 11-4. Buffer and text functions
|
功能 Function |
价值或行动 Value or action |
|---|---|
|
观点 point |
点的字符位置。 Character position of point. |
|
标记 mark |
标记的字符位置。 Character position of mark. |
|
最小点 point-min |
最小字符位置(通常为 1)。 Minimum character position (usually 1). |
|
最大点 point-max |
最大字符位置(通常是缓冲区的大小)。 Maximum character position (usually size of buffer). |
|
博尔普 bolp |
点是否位于行的开头(t或 Whether point is at the beginning of the line (t or |
|
埃尔普 eolp |
点是否位于线的末端。 Whether point is at the end of the line. |
|
波普 bobp |
点是否位于缓冲区的开头。 Whether point is at the beginning of the buffer. |
|
环氧乙烷 eobp |
点是否位于缓冲区末尾。 Whether point is at the end of the buffer. |
|
插入 insert |
在点之后将任意数量的参数(字符串或字符)插入到缓冲区中。 Insert any number of arguments (strings or characters) into the buffer after point. |
|
数字到字符串 number-to-string |
将数字参数转换为字符串。 Convert a numerical argument to a string. |
|
字符串到数字 string-to-number |
将字符串参数转换为数字(整数或浮点数)。 Convert a string argument to a number (integer or floating point). |
|
字符到字符串 char-to-string |
将字符参数转换为字符串。 Convert a character argument to a string. |
|
子串 substring |
给定一个字符串和两个整数索引start和
end ,返回在start之后开始并在
end之前结束的子字符串
。索引从 0 开始。例如,
Given a string and two integer indices start and
end, return the substring starting after
start and ending before
end. Indices start at 0. For example,
|
|
阿雷夫 aref |
数组索引函数,可用于从字符串中返回单个字符;接受一个整数参数并使用 ASCII 代码(在大多数机器上)将字符作为整数返回。例如, Array indexing function that can be used to return individual
characters from strings; takes an integer argument and returns the
character as an integer, using the ASCII code (on most machines). For
example, |
上表中未包含的许多函数都处理缓冲区和文本,包括一些您应该熟悉的用户命令。几个常用的 Emacs 函数使用 区域,它们是缓冲区内的文本区域。使用 Emacs 时,可以通过设置标记和移动光标来划定区域。然而,面向区域的函数(例如kill-region、indent-region和shell-command-on-region——实际上是任何名称中带有region的函数)在Emacs Lisp代码中使用时实际上更加灵活。它们通常采用两个整数参数,用作它们操作的区域边界的字符位置。当交互调用函数时,这些参数默认为 point 和 mark 的值。
Many functions not included in the previous table deal with buffers and text, including some that you should be familiar with as user commands. Several commonly used Emacs functions use regions, which are areas of text within a buffer. When you are using Emacs, you delineate regions by setting the mark and moving the cursor. However, region-oriented functions (such as kill-region, indent-region, and shell-command-on-region—really, any function with region in its name) are actually more flexible when used within Emacs Lisp code. They typically take two integer arguments that are used as the character positions of the boundaries for the region on which they operate. These arguments default to the values of point and mark when the functions are called interactively.
显然,允许点和标记作为交互默认值是一种比仅使用点和标记来描绘区域的方法更通用(因此更理想)的方法。交互功能的r选项使之成为可能。例如,如果我们想编写函数translate-region-into-German,我们将如何开始:
Obviously, allowing point and mark as interactive defaults is a more general (and thus more desirable) approach than one in which only point and mark can be used to delineate regions. The r option to the interactive function makes it possible. For example, if we wanted to write the function translate-region-into-German, here is how we would start:
(defun 将区域翻译成德语(开始结束) (交互式“r”) ...
(defun translate-region-into-German (start end) (interactive "r") ...
当交互调用函数时,interactive的r选项会填充 start和end这两个参数,但如果从其他 Lisp 代码调用它,则必须提供这两个参数。通常的方法是这样的:
The r option to interactive fills in the two arguments start and end when the function is called interactively, but if it is called from other Lisp code, both arguments must be supplied. The usual way to do this is like this:
(将地区翻译成德语(点)(标记))
(translate-region-into-German (point) (mark))
但您不必这样称呼它。如果您想使用此函数编写另一个名为“ translate-buffer-into-German”的函数,则只需将以下内容编写为“包装器”:
But you need not call it in this way. If you wanted to use this function to write another function called translate-buffer-into-German, you would only need to write the following as a "wrapper":
(defun 将缓冲区翻译成德语 ( ) (将区域翻译成德语(最小值)(最大值)))
(defun translate-buffer-into-German ( ) (translate-region-into-German (point-min) (point-max)))
事实上,最好避免在 Lisp 代码中使用点和标记,除非确实有必要这样做;使用局部变量代替。尽量不要将 Lisp 函数编写为用户将调用的命令列表;这种行为更适合宏(参见第 6 章)。
In fact, it is best to avoid using point and mark within Lisp code unless doing so is really necessary; use local variables instead. Try not to write Lisp functions as lists of commands a user would invoke; that sort of behavior is better suited to macros (see Chapter 6).
正则表达式(regexp)提供 处理文本的更强大的方法。尽管大多数 Emacs 新手倾向于避免使用正则表达式的命令,例如Replace-regexp和re-search-forward,但正则表达式在 Lisp 代码中广泛使用。如果没有它们,诸如 Dired 之类的模式和编程语言模式将是不可想象的。正则表达式需要时间和耐心来适应,但这样做对于 Lisp 程序员来说是非常值得的,因为它们是 Emacs 最强大的功能之一,而且很多东西用任何其他方式实现都是不切实际的。
Regular expressions (regexps) provide much more powerful ways of dealing with text. Although most beginning Emacs users tend to avoid commands that use regexps, like replace-regexp and re-search-forward, regular expressions are widely used within Lisp code. Such modes as Dired and the programming language modes would be unthinkable without them. Regular expressions require time and patience to become comfortable with, but doing so is well worth the effort for Lisp programmers, because they are one of the most powerful features of Emacs, and many things are not practical to implement in any other way.
当您尝试正则表达式并尝试掌握它们时,一个有用的技巧是在临时缓冲区中键入一些与您要匹配的内容相对应的文本,然后使用isearch-forward-regexp ( CMs ) 来构建正则表达式。增量搜索的交互式即时反馈可以以 Emacs 完全独特的方式向您展示正则表达式的各个部分。
One trick that can be useful when you are experimenting with regular expressions and trying to get the hang of them is to type some text into a scratch buffer that corresponds to what you're trying to match, and then use isearch-forward-regexp (C-M-s) to build up the regular expression. The interactive, immediate feedback of an incremental search can show you the pieces of the regular expression in action in a way that is completely unique to Emacs.
我们通过几个搜索和替换情况的例子来介绍正则表达式的各种特性;这些例子很容易解释,无需引入大量无关细节。随后,我们将描述 Lisp 函数,这些函数超越了使用正则表达式的简单搜索和替换功能。以下是普通搜索/替换命令无法处理或处理不佳的搜索和替换任务的示例:
We introduce the various features of regular expressions by way of a few examples of search-and-replace situations; such examples are easy to explain without introducing lots of extraneous details. Afterward, we describe Lisp functions that go beyond simple search-and-replace capabilities with regular expressions. The following are examples of searching and replacing tasks that the normal search/replace commands can't handle or handle poorly:
您正在使用 C 语言开发代码,并且希望将这些函数的功能组合read到
readfile一个名为 的新函数中
get。您希望将对这些函数的所有引用替换为对新函数的引用。
You are developing code in C, and you want to combine the
functionality of the functions read and
readfile into a new function called
get. You want to replace all references to these
functions with references to the new one.
您正在使用大纲模式编写troff文档,如第 7 章所述。在大纲模式下,文档部分的标题包含以一个或多个星号开头的行。您想要编写一个名为remove-outline-marks 的函数来删除这些星号,以便您可以在文件上运行troff 。
You are writing a troff document using outline mode, as described in Chapter 7. In outline mode, headers of document sections have lines that start with one or more asterisks. You want to write a function called remove-outline-marks to get rid of these asterisks so that you can run troff on your file.
您希望将文档中出现的所有program (包括programs和 program's)更改为 module / modules / module's,而不将programming更改为 moduleming或将programmer更改为 modulemer。
You want to change all occurrences of program in a document, including programs and program's, to module/modules/module's, without changing programming to moduleming or programmer to modulemer.
您正在编写一些用 Java 重写的 C 软件的文档。您希望将文档中的所有文件名从<filename>.c更改为 <filename>.java,因为 .java是javac编译器使用的扩展名 。
You are working on documentation for some C software that is being rewritten in Java. You want to change all the filenames in the documentation from <filename>.c to <filename>.java, since .java is the extension the javac compiler uses.
您刚刚安装了一个新的 C++ 编译器,它可以用德语打印错误消息。你想要修改 Emacs编译包,使其能够正确解析错误消息(参见第 9 章末尾)。
You just installed a new C++ compiler that prints error messages in German. You want to modify the Emacs compile package so that it can parse the error messages correctly (see the end of Chapter 9).
我们很快就会展示如何使用正则表达式来处理这些示例,我们通过数字来引用这些示例。请注意,这里对正则表达式的讨论虽然比第 3 章更全面,但并未涵盖所有功能;那些它没有涵盖的功能与其他功能是多余的,或者与超出本书范围的概念相关。还需要注意的是,这里描述的正则表达式语法仅适用于 Lisp 字符串;正如我们将看到的, Lisp 字符串的正则表达式语法和用户命令的正则表达式语法(如替换正则表达式)之间有一个重要的区别。
We will soon show how to use regular expressions to deal with these examples, which we refer to by number. Note that this discussion of regular expressions, although more comprehensive than that in Chapter 3, does not cover every feature; those that it doesn't cover are redundant with other features or relate to concepts that are beyond the scope of this book. It is also important to note that the regular expression syntax described here is for use with Lisp strings only; there is an important difference between the regexp syntax for Lisp strings and the regexp syntax for user commands (like replace-regexp), as we will see.
常用表达
最初是理论计算机科学中的一个想法,但它们已经进入了日常实际计算的许多角落和缝隙。用于表示它们的语法可能有所不同,但概念在各处都大致相同。您可能已经知道正则表达式表示法的一个子集:Unix shell 或 Windows 命令提示符用来匹配文件名的通配符。 Emacs 表示法有点不同;它类似于 Perl 语言所使用的语言、诸如ed 和 之类的编辑器以及诸如和 之
vi类的 Unix 软件工具。因此,让我们从类似于 Unix shell 通配符的 Emacs 正则表达式运算符开始,这些运算符在表 11-5中列出。lexgrep
Regular expressions
began
as an idea in theoretical computer science, but they have found their
way into many nooks and crannies of everyday, practical computing.
The syntax used to represent them may vary, but the concepts are much
the same everywhere. You probably already know a subset of regular
expression notation: the wildcard characters used by the Unix shell
or Windows command prompt to match filenames. The Emacs notation is a
bit different; it is similar to those used by the language Perl,
editors like ed and vi and
Unix software tools like lex and
grep. So let's start with the
Emacs regular expression operators that resemble Unix shell wildcard
character, which are listed in Table 11-5.
表 11-5。基本正则表达式运算符
Table 11-5. Basic regular expression operators
|
Emacs操作员 Emacs operator |
相等的 Equivalent |
功能 Function |
|---|---|---|
|
。 . |
|
匹配任何字符。 Matches any character. |
|
|
|
匹配任何字符串。 Matches any string. |
|
|
|
匹配 Matches |
|
|
|
匹配任何小写字母。 Matches any lowercase letter. |
例如,要匹配
Unix shell 中
以programprogram*开头的所有文件名,您可以指定.在 Emacs 中,你会说
program.*.要匹配
shell 中以a到e开头的所有文件名,您可以使用[a-e]*or
[abcde]*;在 Emacs 中,它是
[a-e].*或[abcde].*。换句话说,括号内的破折号指定
字符范围。 [ 6 ]我们将很快提供有关范围和括号字符集的更多信息。
For example, to match all filenames beginning with
program in the Unix shell, you would specify
program*. In Emacs, you would say
program.*. To match all filenames beginning with
a through e in the shell,
you would use [a-e]* or
[abcde]*; in Emacs, it's
[a-e].* or [abcde].*. In other
words, the dash within the brackets specifies a
range of characters.[6] We will provide more on ranges and
bracketed character sets shortly.
要指定用作正则表达式运算符的字符,您需要在其前面添加双反斜杠,如
\\*匹配星号。为什么要使用双反斜杠?原因与 Emacs Lisp 读取和解码字符串的方式有关。当 Emacs 读取 Lisp 程序中的字符串时,它会解码反斜杠转义字符,从而将双反斜杠转换为单反斜杠。如果字符串用作正则表达式(即,如果将其传递给需要正则表达式参数的函数),则该函数使用单个反斜杠作为正则表达式语法的一部分。例如,给出以下 Lisp 行:
To specify a character that is used as a regular expression operator,
you need to precede it with a double-backslash, as in
\\* to match an asterisk. Why a double backslash?
The reason has to do with the way Emacs Lisp reads and decodes
strings. When Emacs reads a string in a Lisp program, it decodes the
backslash-escaped characters and thus turns double backslashes into
single backslashes. If the string is being used as a regular
expression—that is, if it is being passed to a function that
expects a regular expression argument—that function uses the
single backslash as part of the regular expression syntax. For
example, given the following line of Lisp:
(替换正则表达式“fred\\*”“bob*”)
(replace-regexp "fred\\*" "bob*")
Lisp 解释器将字符串解码fred\\*为
fred\*并将其传递给replace-regexp命令。Replace-regexp命令理解
fred\*为fred后跟一个(字面的)星号。但请注意, replace-regexp的第二个参数
不是正则表达式,因此bob*根本不需要反斜杠转义星号
。另请注意,如果您要将 this 作为用户命令调用,则不需要加倍反斜杠,也就是说,您将键入Mx Replace-regexp Enter后跟fred\*和bob*。 Emacs 以不同的方式解码从迷你缓冲区读取的字符串。
the Lisp interpreter decodes the string fred\\* as
fred\* and passes it to the replace-regexp command. The replace-regexp command understands
fred\* to mean fred followed by
a (literal) asterisk. Notice, however, that the second argument to
replace-regexp is not a regular
expression, so there is no need to backslash-escape the asterisk in
bob* at all. Also notice that if you were to
invoke the this as a user command, you would not need to double the
backslash, that is, you would type M-x
replace-regexp Enter followed by fred\* and bob*. Emacs decodes strings read from the
minibuffer differently.
Emacs 中的正则表达式运算符(就其本身而言)实际上意味着与Unix shell 中
*的不同的东西
:它意味着“零次或多次出现 . 之前的内容”。因此,因为 .匹配任何字符,
意味着“任何字符出现零次或多次”,即任何字符串,包括空字符串。任何内容都可以放在: 例如,匹配“rea”后跟零个或多个 d;匹配“file”后跟零个或多个数字。**.**read*file[0-9]*
The * regular expression operator in Emacs (by
itself) actually means something different from the
* in the Unix shell: it means
"zero or more occurrences of whatever is before the
*." Thus, because
. matches any character, .*
means "zero or more occurrences of any
character," that is, any string at all, including
the empty string. Anything can precede a *: for
example, read* matches
"rea" followed by zero or more
d's; file[0-9]* matches
"file" followed by zero or more
digits.
两个运算符密切相关*。第一个是+,它匹配它之前出现的一个或多个内容。因此,read+匹配“read”和“readdddd”,但不匹配“rea”,并且
file[0-9]+要求“file”后面至少有一位数字。第二个是
?,它匹配零次或一次出现在其前面的任何内容(即,使其成为可选)。
html?匹配“htm”或“html”,并
file[0-9]?匹配“file”后跟一位可选数字。
Two operators are closely related to *. The first
is +, which matches one or more occurrences of
whatever precedes it. Thus, read+ matches
"read" and
"readdddd" but not
"rea," and
file[0-9]+ requires that there be at least one
digit after "file." The second is
?, which matches zero or one occurrence of
whatever precedes it (i.e., makes it optional).
html? matches
"htm" or
"html," and
file[0-9]? matches
"file" followed by one optional
digit.
在我们继续讨论其他运算符之前,我们先对字符集和范围进行一些评论。首先,您可以在单个字符集中指定多个范围。因此,该集合
[A-Za-z]可用于指定所有字母字符;这比非便携式的要好
[A-z]。也可以将范围与集合中的字符列表组合起来;例如,[A-Za-z_]
表示所有字母字符加下划线,即 C 中标识符名称中允许的所有字符。如果指定
^为集合中的第一个字符,则它充当“非”运算符;该集合匹配所有不属于 后面的字符的字符
^。例如,[^A-Za-z]
匹配所有非字母字符。
Before we move on to other operators, a few more comments about
character sets and ranges are in order. First, you can specify more
than one range within a single character set. The set
[A-Za-z] can thus be used to specify all
alphabetic characters; this is better than the nonportable
[A-z]. Combining ranges with lists of characters
in sets is also possible; for example, [A-Za-z_]
means all alphabetic characters plus underscore, that is, all
characters allowed in the names of identifiers in C. If you give
^ as the first character in a set, it acts as a
"not" operator; the set matches all
characters that aren't the characters after the
^. For example, [^A-Za-z]
matches all nonalphabetic characters.
^字符集中除第一个字符之外的任何位置都没有特殊含义;这只是插入符字符。相反,-如果它在集合中首先给出,则没有特殊含义;对于 也是如此
]。但是,我们不建议您使用此快捷方式;相反,为了安全起见,您应该使用双反斜杠转义这些字符。非特殊字符前面的双反斜杠通常仅表示该字符 - 但请注意!一些字母和标点符号用作正则表达式运算符,下一节将介绍其中一些。我们列出了稍后在双反斜杠转义时成为运算符的“陷阱”字符。当在范围之外使用时,该^字符具有不同的含义,我们很快就会看到。
A ^ anywhere other than first in a character set
has no special meaning; it's just the caret
character. Conversely, - has no special meaning if
it is given first in the set; the same is true for
]. However, we don't recommend
that you use this shortcut; instead, you should
double-backslash-escape these characters just to be on the safe side.
A double backslash preceding a nonspecial character usually means
just that character—but watch it! A few letters and punctuation
characters are used as regular expression operators, some of which
are covered in the following section. We list "booby
trap" characters that become operators when
double-backslash-escaped later. The ^ character
has a different meaning when used outside of ranges, as
we'll see soon.
如果你想得到*, +, 或
?
对多个字符进行操作时,可以使用\\(和\\)
运算符进行分组。请注意,在这种情况下(以及随后的其他情况),反斜杠是运算符的一部分。 (所有非基本正则表达式运算符都包含反斜杠,以避免使太多字符变得“特殊”。这是 Emacs 正则表达式与其他环境(如 Perl)中使用的正则表达式最深刻的区别,因此您需要了解它需要特别注意。)正如我们之前看到的,这些字符需要双反斜杠转义,以便 Emacs 正确解码它们。如果紧随其后的是基本运算符之一,则它作用于and
\\)内的整个组。例如,
匹配空字符串、“read”、“readread”等,并
匹配“read”或“readfile”。现在我们可以使用以下 Lisp 代码来处理示例 1,即本节开头给出的第一个示例:\\(\\)\\(read\\)*read\\(file\\)?
If you want to get *, +, or
? to
operate on more than one character,
you can use the \\( and \\)
operators for grouping. Notice that, in this case (and others to
follow), the backslashes are part of the operator. (All of the
nonbasic regular expression operators include backslashes so as to
avoid making too many characters
"special." This is the most
profound way in which Emacs regular expressions differ from those
used in other environments, like Perl, so it's
something to which you'll need to pay careful
attention.) As we saw before, these characters need to be
double-backslash-escaped so that Emacs decodes them properly. If one
of the basic operators immediately follows \\), it
works on the entire group inside the \\( and
\\). For example, \\(read\\)*
matches the empty string, "read,"
"readread," and so on, and
read\\(file\\)? matches
"read" or
"readfile." Now we can handle
Example 1, the first of the examples given at the beginning of this
section, with the following Lisp code:
(替换正则表达式“读\\(文件\\)?”“获取”)
(replace-regexp "read\\(file\\)?" "get")
交替运算符\\|是“一个或另一个”运算符;它匹配它之前的任何内容或之后的任何内容。
\\|对待括号组与基本运算符不同。它不要求带括号的组处理多个字符的子表达式,而是尽可能向左和向右延伸,直到到达正则表达式 a \\(、 a\\)或 another的开头或结尾\\|。一些例子应该可以让这一点更清楚:
The alternation operator \\| is a
"one or the other" operator; it
matches either whatever precedes it or whatever comes after it.
\\| treats parenthesized groups differently from
the basic operators. Instead of requiring parenthesized groups to
work with subexpressions of more than one character, its
"power" goes out to the left and
right as far as possible, until it reaches the beginning or end of
the regexp, a \\(, a \\), or
another \\|. Some examples should make this
clearer:
read\\|get匹配“读”或“获取”
read\\|get matches
"read" or
"get"
readfile\\|read\\|get匹配“readfile”、“read”或“get”
readfile\\|read\\|get matches
"readfile",
"read," or
"get"
\\(read\\|get\\)file匹配“readfile”或“getfile”
\\(read\\|get\\)file matches
"readfile" or
"getfile"
在第一个示例中, 的效果\\|
延伸到正则表达式的两端。在第二个中,第一个的效果\\|延伸到左侧正则表达式的开头和\\|右侧第二个正则表达式的开头。在第三个中,它延伸到反斜杠括号。
In the first example, the effect of the \\|
extends to both ends of the regular expression. In the second, the
effect of the first \\| extends to the beginning
of the regexp on the left and to the second \\| on
the right. In the third, it extends to the backslash-parentheses.
常规的另一个重要类别 表达式运算符与指定字符串的上下文有关,即字符串周围的文本。在第 3 章中,我们看到了 单词搜索命令,这些命令在增量搜索中作为选项调用。这些是上下文规范的特殊情况;在这种情况下,上下文是字符串两侧的单词分隔字符,例如空格或标点符号。
Another important category of regular expression operators has to do with specifying the context of a string, that is, the text around it. In Chapter 3 we saw the word-search commands, which are invoked as options within incremental search. These are special cases of context specification; in this case, the context is word-separation characters, for example, spaces or punctuation, on both sides of the string.
正则表达式最简单的上下文运算符是
^和$,这两个基本运算符分别用在正则表达式的开头和结尾。^仅当正则表达式的其余部分位于行的开头时,该运算符才会匹配它;$导致其前面的正则表达式仅在位于行尾时才匹配。在示例 2 中,我们需要一个函数来匹配行开头出现的一个或多个星号;这会做到这一点:
The simplest context operators for regular expressions are
^ and $, two more basic
operators that are used at the beginning and end of regular
expressions respectively. The ^ operator causes
the rest of the regular expression to match only if it is at the
beginning of a line; $ causes the regular
expression preceding it to match only if it is at the end of a line.
In Example 2, we need a function that matches occurrences of one or
more asterisks at the beginning of a line; this will do it:
(defun 删除轮廓标记 ( ) “删除在大纲模式下创建的节标题标记。” (交互的) (替换正则表达式“^\\*+”“”))
(defun remove-outline-marks ( ) "Remove section header marks created in outline-mode." (interactive) (replace-regexp "^\\*+" ""))
此函数查找以一个或多个星号开头的行(
\\*星号是字面意思,意思
+是“一个或多个”),并用空字符串“”替换星号,从而删除它们。
This function finds lines that begin with one or more asterisks (the
\\* is a literal asterisk and the
+ means "one or
more"), and it replaces the asterisk(s) with the
empty string "", thus deleting them.
请注意,^and$
不能用在用于匹配跨越多行的字符串的正则表达式中间。相反,您可以将\n(换行符)放入正则表达式中以匹配此类字符串。您可能想要使用的另一个此类字符是\tTab。当
^和$与字符串而不是缓冲区的正则表达式搜索一起使用时,它们分别匹配字符串的开头和结尾;本章稍后介绍的函数string-match可用于对字符串进行正则表达式搜索。
Note that ^ and $
can't be used in the middle of regular expressions
that are intended to match strings that span more than one line.
Instead, you can put \n (for Newline) in your
regular expressions to match such strings. Another such character you
may want to use is \t for Tab. When
^ and $ are used with regular
expression searches on strings instead of buffers, they match
beginning- and end-of-string, respectively; the function string-match, described later in this chapter,
can be used to do regular expression search on strings.
下面是一个复杂正则表达式的真实示例,它涵盖了我们迄今为止所见过的运算符:sentence-end ,Emacs 使用一个变量来识别句子运动命令(如前向句子(Me ))的句子结尾 。其值为:
Here is a real-life example of a complex regular expression that covers the operators we have seen so far: sentence-end, a variable Emacs uses to recognize the ends of sentences for sentence motion commands like forward-sentence (M-e). Its value is:
"[.?!][]\"')}]*\\($\\|\t\\| \\)[ \t\n]*"
"[.?!][]\"')}]*\\($\\|\t\\| \\)[ \t\n]*"
让我们一块一块地看一下。第一个字符集 ,[.?!]匹配句点、问号或感叹号(其中前两个是正则表达式运算符,但它们在字符集中没有特殊含义)。下一部分[]\"')}]*由包含右括号、双引号、单引号、右括号和右花括号的字符集组成。 A
*位于集合之后,表示集合中任何字符出现零次或多次匹配。到目前为止,这个正则表达式匹配一个句子结束标点符号,后跟零个或多个结束引号、括号或大括号。接下来是组\\($\\|\t\\| \\),它匹配三个替代项$(行尾)、
Tab或两个空格中的任何一个。最后,[
\t\n]*匹配零个或多个空格、制表符或换行符。因此,句子结束字符后面可以是行尾或空格(至少两个)、制表符和换行符的组合。
Let's look at this piece by piece. The first
character set, [.?!], matches a period, question
mark, or exclamation mark (the first two of these are regular
expression operators, but they have no special meaning within
character sets). The next part, []\"')}]*,
consists of a character set containing right bracket, double quote,
single quote, right parenthesis, and right curly brace. A
* follows the set, meaning that zero or more
occurrences of any of the characters in the set matches. So far,
then, this regexp matches a sentence-ending punctuation mark followed
by zero or more ending quotes, parentheses, or curly braces. Next,
there is the group \\($\\|\t\\| \\), which matches
any of the three alternatives $ (end of line),
Tab, or two spaces. Finally, [
\t\n]* matches zero or more spaces, tabs, or newlines. Thus
the sentence-ending characters can be followed by end-of-line or a
combination of spaces (at least two), tabs, and newlines.
^除了and
之外,还有其他上下文运算符$;其中两个可用于使正则表达式搜索就像单词搜索一样。运算符
\\<和\\>分别匹配单词的开头和结尾。有了这些,我们就可以部分解决示例 3 的问题。正则表达式
\\<program\\>匹配“program”,但不匹配“programmer”或“programming”(它也不会匹配“microprogram”)。到目前为止,一切都很好;但是,它不会匹配“program's”或“programs”。为此,我们需要一个更复杂的正则表达式:
There are other context operators besides ^ and
$; two of them can be used to make regular
expression search act like word search. The operators
\\< and \\> match the
beginning and end of a word, respectively. With these we can go part
of the way toward solving Example 3. The regular expression
\\<program\\> matches
"program" but not
"programmer" or
"programming" (it also
won't match
"microprogram"). So far so good;
however, it won't match
"program's" or
"programs." For this, we need a
more complex regular expression:
\\<程序\\('s\\|s\\)?\\>\\<program\\('s\\|s\\)?\\>该表达式的意思是“以program开头的单词, 后面可选地跟撇号 s 或仅 s”。就匹配正确的单词而言,这很有效。
This expression means, "a word beginning with program followed optionally by apostrophe s or just s." This does the trick as far as matching the right words goes.
还有一块
缺少:用“模块”替换“程序”,同时保持任何
s或 's不变的能力。这导致了我们将在此处介绍的最终正则表达式功能:检索匹配字符串的部分以供以后使用的能力。前面的正则表达式确实是作为Replace-regexp的搜索字符串给出的正确正则表达式。至于替换字符串,答案是module\\1;换句话说,所需的 Lisp 代码是:
There is still one piece
missing: the ability to replace
"program" with
"module" while leaving any
s or 's untouched. This leads
to the final regular expression feature we will cover here: the
ability to retrieve portions of the matched string for later use. The
preceding regular expression is indeed the correct one to give as the
search string for replace-regexp. As
for the replace string, the answer is module\\1;
in other words, the required Lisp code is:
(替换正则表达式“\\<程序\\('s\\|s\\)?\\>”“模块\\1”)(replace-regexp "\\<program\\('s\\|s\\)?\\>" "module\\1")实际上,这意味着“替换与and
\\1内的子表达式匹配的匹配字符串部分”。它是唯一可用于替换的与正则表达式相关的运算符。在这种情况下,这意味着如果匹配是“program's”,则意味着在替换字符串中
使用 ' ;如果匹配是“programs”,则意味着在替换字符串中使用 ';如果匹配只是“program”,则不使用任何内容。结果是“模块”正确替换为“程序”,“模块”替换为“程序”,以及“模块的”替换为“程序的”。\\(\\)ss
The \\1 means, in effect,
"substitute the portion of the matched string that
matched the subexpression inside the \\( and
\\)." It is the only
regular-expression-related operator that can be used in replacements.
In this case, it means to use 's in the replace
string if the match was
"program's,"
s if the match was
"programs," or nothing if the match
was just "program." The result is
the correct substitution of
"module" for
"program,"
"modules" for
"programs," and
"module's" for
"program's."
此功能的另一个示例解决了示例 4 的问题。要匹配文件名 <filename>.c并将其替换为 <filename>.java,请使用 Lisp 代码:
Another example of this feature solves Example 4. To match filenames <filename>.c and replace them with <filename>.java, use the Lisp code:
(替换正则表达式“\\([a-zA-Z0-9_]+\\)\\.c”“\\1.java”)
(replace-regexp "\\([a-zA-Z0-9_]+\\)\\.c" "\\1.java")
请记住这一点\\。表示字面上的点 (.)。另请注意,文件名模式(与一系列一个或多个字母数字或下划线匹配)被搜索字符串中的\\(和包围\\),其唯一目的是稍后使用
\\1.
Remember that \\. means a literal dot
(.). Note also that the filename pattern (which
matches a series of one or more alphanumerics or underscores) was
surrounded by \\( and \\) in
the search string for the sole purpose of retrieving it later with
\\1.
实际上,\\1操作员只是更强大设施的特例(正如您可能已经猜到的)。一般来说,如果用
\\(and包围正则表达式的一部分\\),则会保存与括号内的子表达式匹配的字符串。当指定替换字符串时,可以使用 检索已保存的子字符串
\\
n,其中
n是括号子表达式从左到右的编号,从 1 开始。括号表达式可以嵌套;它们对应的
编号按照分隔符从左到右\\
n的顺序分配。\\(
Actually, the \\1 operator is only a special case
of a more powerful facility (as you may have guessed). In general, if
you surround a portion of a regular expression with
\\( and \\), the string
matching the parenthesized subexpression is saved. When you specify
the replace string, you can retrieve the saved substrings with
\\
n, where
n is the number of the parenthesized
subexpression from left to right, starting with 1. Parenthesized
expressions can be nested; their corresponding
\\
n numbers are
assigned in order of their \\( delimiter from left
to right.
充分利用此功能的 Lisp 代码往往包含复杂的正则表达式。 Emacs 自己的 Lisp 代码中最好的例子是compilation-error-regexp-alist ,它是编译 包(在第 9 章中讨论)用于解析来自编译器的错误消息的正则表达式列表。以下是摘自 Emacs 源代码的摘录(它太长了,无法完整重现;请参阅下面的一些提示,了解如何找到实际文件以充分研究它):
Lisp code that takes full advantage of this feature tends to contain complicated regular expressions. The best example of this in Emacs's own Lisp code is compilation-error-regexp-alist, the list of regular expressions the compile package (discussed in Chapter 9) uses to parse error messages from compilers. Here is an excerpt, adapted from the Emacs source code (it's become much too long to reproduce in its entirety; see below for some hints on how to find the actual file to study in its full glory):
(defvar 编译-错误-regexp-alist
'(
;;笔记!另请参阅下面的 grep-regexp-alist。
;; 4.3BSD grep、cc、lint 传递 1:
;; /usr/src/foo/foo.c(8): 警告:w 可以在设置之前使用
;;或 GNU 实用程序:
;; foo.c:8:错误消息
;;或 HP-UX 7.0 fc:
;; foo.f :16 一些可怕的错误消息
;;或带有列的 GNU 实用程序 (GNAT 1.82):
;; foo.adb:2:1:单元名称与文件名不匹配
;;或带有列和程序名称:
;; jade:dbcommon.dsl:133:17:E: 函数调用缺少参数
;;
;;我们坚持要求数字后跟冒号或结束符
;; paren,因为否则这几乎匹配任何东西
;;包含一个周围有空格的数字。
;;我们坚持文件名中包含非数字
;;这样我们就不会将文件名误认为是命令名
;;并以行号作为文件名。
("\\([a-zA-Z][-a-zA-Z._0-9]+: ?\\)?\
\\([a-zA-Z]?:?[^:( \t\n]*[^:( \t\n0-9][^:( \t\n]*\\)[:( ][ \t]*\\([0-9]+\\)\
\\([) \t]\\|:\\(\\([0-9]+:\\)\\|[0-9]*[^:0-9]\\)\\) “ 2 3 6)
;;微软C/C++:
;; Keyboard.c(537):警告 C4005:'min':宏重新定义
;; d:\tmp\test.c(23) : 错误 C2143: 语法错误: 缺少 ';'前
'如果'
;;这过去的选择性较少,并且允许除
;;行号周围有括号,但这引起了混乱
;; GNU 风格的错误消息。
;;这用于拒绝文件名中的空格和破折号,
;;但它们现在有效;所以我对错误更加严格
;;以下消息。
("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)) \
: \\(错误\\|警告\\) C[0-9]+:" 1 3)
;; Caml编译器:
;;文件“foobar.ml”,第 5-8 行,第 20-155 个字符:blah blah
("^文件 \"\\([^,\" \n\t]+\\)\",行数? \\([0-9]+\\)[-0-9]*,字符数? \
\\([0-9]+\\)" 1 2 3)
;; Cray C 编译器错误消息
("\\(cc\\| cft\\)-[0-9]+ c\\(c\\|f77\\): 错误 \\([^,\n]+, \\)* 文件= \
\\([^,\n]+\\), 行 = \\([0-9]+\\)" 4 5)
;; Perl -w:
;; automake 第 922 行的语法错误,靠近“':'”
;; Perl 调试痕迹
;; store::odrecall('File_A', 'x2') 在 store.pm 第 90 行调用
(".* 在 \\([^ \n]+\\) 行 \\([0-9]+\\)[,.\n]" 1 2)
;;请参阅http://ant.apache.org/faq.html
;; Ant Java:适用于 jikes
("^\\s-*\\[[^]]*\\]\\s-*\\(.+\\):\\([0-9]+\\):\\([ 0-9]+\\):[0-9]+:[0-9]\
+:" 1 2 3)
;; Ant Java:适用于 javac
("^\\s-*\\[[^]]*\\]\\s-*\\(.+\\):\\([0-9]+\\):" 1 2)
)(defvar compilation-error-regexp-alist
'(
;; NOTE! See also grep-regexp-alist, below.
;; 4.3BSD grep, cc, lint pass 1:
;; /usr/src/foo/foo.c(8): warning: w may be used before set
;; or GNU utilities:
;; foo.c:8: error message
;; or HP-UX 7.0 fc:
;; foo.f :16 some horrible error message
;; or GNU utilities with column (GNAT 1.82):
;; foo.adb:2:1: Unit name does not match file name
;; or with column and program name:
;; jade:dbcommon.dsl:133:17:E: missing argument for function call
;;
;; We'll insist that the number be followed by a colon or closing
;; paren, because otherwise this matches just about anything
;; containing a number with spaces around it.
;; We insist on a non-digit in the file name
;; so that we don't mistake the file name for a command name
;; and take the line number as the file name.
("\\([a-zA-Z][-a-zA-Z._0-9]+: ?\\)?\
\\([a-zA-Z]?:?[^:( \t\n]*[^:( \t\n0-9][^:( \t\n]*\\)[:(][ \t]*\\([0-9]+\\)\
\\([) \t]\\|:\\(\\([0-9]+:\\)\\|[0-9]*[^:0-9]\\)\\)" 2 3 6)
;; Microsoft C/C++:
;; keyboard.c(537) : warning C4005: 'min' : macro redefinition
;; d:\tmp\test.c(23) : error C2143: syntax error : missing ';' before
'if'
;; This used to be less selective and allow characters other than
;; parens around the line number, but that caused confusion for
;; GNU-style error messages.
;; This used to reject spaces and dashes in file names,
;; but they are valid now; so I made it more strict about the error
;; message that follows.
("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)) \
: \\(error\\|warning\\) C[0-9]+:" 1 3)
;; Caml compiler:
;; File "foobar.ml", lines 5-8, characters 20-155: blah blah
("^File \"\\([^,\" \n\t]+\\)\", lines? \\([0-9]+\\)[-0-9]*, characters? \
\\([0-9]+\\)" 1 2 3)
;; Cray C compiler error messages
("\\(cc\\| cft\\)-[0-9]+ c\\(c\\|f77\\): ERROR \\([^,\n]+, \\)* File = \
\\([^,\n]+\\), Line = \\([0-9]+\\)" 4 5)
;; Perl -w:
;; syntax error at automake line 922, near "':'"
;; Perl debugging traces
;; store::odrecall('File_A', 'x2') called at store.pm line 90
(".* at \\([^ \n]+\\) line \\([0-9]+\\)[,.\n]" 1 2)
;; See http://ant.apache.org/faq.html
;; Ant Java: works for jikes
("^\\s-*\\[[^]]*\\]\\s-*\\(.+\\):\\([0-9]+\\):\\([0-9]+\\):[0-9]+:[0-9]\
+:" 1 2 3)
;; Ant Java: works for javac
("^\\s-*\\[[^]]*\\]\\s-*\\(.+\\):\\([0-9]+\\):" 1 2)
)这是一个元素列表,每个元素至少包含三个部分:一个正则表达式和两个数字。正则表达式与特定编译器或工具使用的格式的错误消息相匹配。第一个数字告诉 Emacs 哪个匹配的子表达式包含错误消息中的文件名;第二个数字指定哪个子表达式包含行号。 (末尾还可以有其他部分:第三个数字给出错误的列号位置(如果有),以及用于从错误消息中找到的片段生成真实文件名的任意数量的格式字符串(如果有关这些的更多详细信息,请查看实际文件,如下所述。)
This is a list of elements that have at least three parts each: a regular expression and two numbers. The regular expression matches error messages in the format used by a particular compiler or tool. The first number tells Emacs which of the matched subexpressions contains the filename in the error message; the second number designates which of the subexpressions contains the line number. (There can also be additional parts at the end: a third number giving the position of the column number of the error, if any, and any number of format strings used to generate the true filename from the piece found in the error message, if needed. For more details about these, look at the actual file, as described below.)
例如,处理 Perl 的列表中的元素包含正则表达式:
For example, the element in the list dealing with Perl contains the regular expression:
".* 在 \\([^ \n]+\\) 行 \\([0-9]+\\)[,.\n]"
".* at \\([^ \n]+\\) line \\([0-9]+\\)[,.\n]"
后跟 1 和 2,表示第一个带括号的子表达式包含文件名,第二个包含行号。因此,如果您打开了 Perl 的警告(当然,您总是这样做),您可能会收到如下错误消息:
followed by 1 and 2, meaning that the first parenthesized subexpression contains the filename and the second contains the line number. So if you have Perl's warnings turned on—you always do, of course—you might get an error message such as this:
Monthly_orders.pl 第 1822 行的语法错误,靠近“$”
syntax error at monthly_orders.pl line 1822, near "$"
正则表达式会忽略
at之前的所有内容。然后,它找到
monthly_orders.pl,即文件名,作为第一个子表达式“”(一个或多个非空白、非换行符)的匹配,并找到行号1822,作为第二个子表达式“ ”(一个或[^
\n]+多个非空白、非换行符)的匹配。[0-9]+更多数字)。
The regular expression ignores everything up to
at. Then it finds
monthly_orders.pl, the filename, as the match to
the first subexpression "[^
\n]+" (one or more nonblank, nonnewline
characters), and it finds 1822, the line number, as the match to the
second subexpression
"[0-9]+" (one or
more digits).
大多数情况下,这些正则表达式在其定义中都有很好的记录。深入理解它们仍然是一个挑战,编写它们更是如此!假设我们想要通过向此列表添加一个元素来处理示例 5,以便我们的新 C++ 编译器以德语打印错误消息。特别是,它打印如下错误消息:
For the most part, these regular expressions are documented pretty well in their definitions. Understanding them in depth can still be a challenge, and writing them even more so! Suppose we want to tackle Example 5 by adding an element to this list for our new C++ compiler that prints error messages in German. In particular, it prints error messages like this:
Fehler auf Zeilelinenum中filename:text of error message
Fehler auf Zeilelinenuminfilename:text of error message
这是我们要添加到compilation-error-regexp-alist中的元素:
Here is the element we would add to compilation-error-regexp-alist:
("Fehler auf Zeile \\([0-9]+\\) in \\([^: \t]+\\):" 2 1)("Fehler auf Zeile \\([0-9]+\\) in \\([^: \t]+\\):" 2 1)在这种情况下,第二个带括号的子表达式与文件名匹配,第一个子表达式与行号匹配。
In this case, the second parenthesized subexpression matches the filename, and the first matches the line number.
要将其添加到compilation-error-regexp-alist中,我们需要将此行放入.emacs中:
To add this to compilation-error-regexp-alist, we need to put this line in .emacs:
(setq 编译-错误-regexp-alist
(cons '("Fehler auf Zeile \\([0-9]+\\) in \\([^: \t]+\\):" 2 1)
编译错误正则表达式列表))(setq compilation-error-regexp-alist
(cons '("Fehler auf Zeile \\([0-9]+\\) in \\([^: \t]+\\):" 2 1)
compilation-error-regexp-alist))请注意这个示例与我们向auto-mode-alist添加对新语言模式的支持的示例(来自第 9 章)有何相似之处。
Notice how this example resembles our example (from Chapter 9) of adding support for a new language mode to auto-mode-alist.
表 11-6总结 我们对正则表达式运算符的讨论以及所涵盖的所有运算符的参考列表。
Table 11-6 concludes our discussion of regular expression operators with a reference list of all the operators covered.
表 11-6。正则表达式运算符
Table 11-6. Regular expression operators
|
操作员 Operator |
功能 Function |
|---|---|
|
。 . |
匹配任何字符。 Match any character. |
|
|
匹配 0 次或多次出现的前面的字符或组。 Match 0 or more occurrences of preceding char or group. |
|
|
匹配 1 次或多次出现的前面的字符或组。 Match 1 or more occurrences of preceding char or group. |
|
|
匹配 0 或 1 次出现的前面的字符或组。 Match 0 or 1 occurrences of preceding char or group. |
|
|
字符集;见下文。 Set of characters; see below. |
|
|
开始一个小组。 Begin a group. |
|
|
结束一组。 End a group. |
|
|
匹配 \\| 之前或之后的子表达式。 Match the subexpression before or after \\|. |
|
|
在正则表达式的开头,匹配行或字符串的开头。 At beginning of regexp, match beginning of line or string. |
|
|
在正则表达式的末尾,匹配行或字符串的末尾。 At end of regexp, match end of line or string. |
|
|
匹配正则表达式中的换行符。 Match Newline within a regexp. |
|
|
匹配正则表达式中的制表符。 Match Tab within a regexp. |
|
|
匹配单词的开头。 Match beginning of word. |
|
|
匹配词尾。 Match end of word. |
|
以下运算符在字符集中有意义: The following operators are meaningful within character sets: | |
|
|
在集合开始时,将集合视为不匹配的字符。 At beginning of set, treat set as chars not to match. |
|
|
指定字符范围。 Specify range of characters. |
|
以下内容在正则表达式替换字符串中也有意义: The following is also meaningful in regexp replace strings: | |
|
|
Substitute portion of match within the |
最后,以下字符在双反斜杠转义时是运算符(此处不讨论):b,
B, c, C,
w, W, s,
S, =, _, ', 和`。因此,当双反斜杠转义时,这些都是“陷阱”。其中一些行为与您在 Perl 和 Java 正则表达式中可能遇到的字符类别名类似。
Finally, the following characters are operators (not discussed here)
when double-backslash-escaped: b,
B, c, C,
w, W, s,
S, =, _,
', and `. Thus, these are
"booby traps" when
double-backslash-escaped. Some of these behave similarly to the
character class aliases you may have encountered in Perl and Java
regular expressions.
如上所述,完整的自动模式列表具有比本书更多的条目和文档。compile.el定义它的模块还包含使用它的函数。
学习如何使用 Emacs Lisp(以及发现您可能没有意识到自己可以做的事情)的最佳方法之一是浏览与您想要实现的目标类似的标准模块的实现,或者这很有趣。但你如何找到它们呢?
As mentioned above, the full auto-mode-alist has a lot more entries and
documentation than fit in this book. The
compile.el module in which it is defined also
contains functions that use it. One of the best ways to learn how to
use Emacs Lisp (as well as discovering things you might not have even
realized you can do) is to browse through the implementations of
standard modules that are similar to what you're
trying to achieve, or that are simply interesting. But how do you
find them?
手动方法是查看变量load-path的值。这是 Emacs 在需要加载库文件本身时参考的变量,因此您要查找的任何库都必须位于这些目录之一中。 (这个变量将在本章的最后一节中进一步讨论。)问题是,如果你查看该变量的当前值,你就会发现,它包含大量需要你费力浏览的目录,这将导致每次你对图书馆感到好奇时都会变得非常乏味。 (查看变量值的一种简单方法是通过帮助的“描述变量”功能Ch v。)
The manual way is to look at the value of the variable load-path. This is the variable Emacs consults when it needs to load a library file itself, so any library you're looking for must be in one of these directories. (This variable is discussed further in the final section of this chapter.) The problem, as you will see if you look at the current value of the variable, is that it contains a large number of directories for you to wade through, which would be pretty tedious each time you're curious about a library. (An easy way to see the variable's value is through Help's "Describe variable" feature, C-h v.)
其中一位作者编写了例 11-1中列出的命令来解决这个问题,并经常使用它来轻松地窥探使 Emacs 运行的大部分源文件。如果您不想手动将整个函数输入到.emacs中,可以从本书的网站下载它网站,http://www.oreilly.com/catalog/gnu3。
One of the authors wrote the command listed in Example 11-1 to address this problem and uses it regularly to easily snoop on the source files that make much of Emacs run. If you don't want to type this entire function into your .emacs by hand, you can download it from this book's web site, http://www.oreilly.com/catalog/gnu3.
例11-1。查找库文件
Example 11-1. find-library-file
(defun 查找库文件(库)
“采用单个参数 LIBRARY,作为要搜索的库文件。
直接搜索 LIBRARY(如果相对于当前目录,
或绝对),然后按顺序搜索加载路径中的目录。它
将测试没有添加扩展名的 LIBRARY,然后使用 .el,最后
与 .elc。如果在搜索中找到文件,则会访问该文件。如果没有
发现时,会发出错误信号。请注意扩展搜索的顺序
与负载函数相反。”
(交互式“s查找库文件:”)
(let ((path (cons "" load-path)) 精确匹配 elc 测试发现)
(同时(和(不匹配)路径)
(setq test(concat(车路径)“/”库)
匹配(如果(条件情况为零
(文件可读-p测试)
(错误为零))
测试)
路径(cdr路径)))
(setq 路径 (cons "" 加载路径))
(或匹配
(同时(和(不是 elc)路径)
(setq test(concat(汽车路径)“/”库“.elc”)
elc (if (条件情况为零
(文件可读-p测试)
(错误为零))
测试)
路径(cdr路径))))
(setq 路径 (cons "" 加载路径))
(同时(和(不匹配)路径)
(setq test(concat(汽车路径)“/”库“.el”)
匹配(如果(条件情况为零
(文件可读-p测试)
(错误为零))
测试)
路径(cdr路径)))
(找到setq(或匹配elc))
(如果找到
(程序
(查找文件找到)
(并匹配 elc
(消息“(库文件 %s 存在)”elc)
(坐1))
(消息“找到库文件 %s”已找到))
(错误“未找到库文件\”%s\”。”库))))(defun find-library-file (library)
"Takes a single argument LIBRARY, being a library file to search for.
Searches for LIBRARY directly (in case relative to current directory,
or absolute) and then searches directories in load-path in order. It
will test LIBRARY with no added extension, then with .el, and finally
with .elc. If a file is found in the search, it is visited. If none
is found, an error is signaled. Note that order of extension searching
is reversed from that of the load function."
(interactive "sFind library file: ")
(let ((path (cons "" load-path)) exact match elc test found)
(while (and (not match) path)
(setq test (concat (car path) "/" library)
match (if (condition-case nil
(file-readable-p test)
(error nil))
test)
path (cdr path)))
(setq path (cons "" load-path))
(or match
(while (and (not elc) path)
(setq test (concat (car path) "/" library ".elc")
elc (if (condition-case nil
(file-readable-p test)
(error nil))
test)
path (cdr path))))
(setq path (cons "" load-path))
(while (and (not match) path)
(setq test (concat (car path) "/" library ".el")
match (if (condition-case nil
(file-readable-p test)
(error nil))
test)
path (cdr path)))
(setq found (or match elc))
(if found
(progn
(find-file found)
(and match elc
(message "(library file %s exists)" elc)
(sit-for 1))
(message "Found library file %s" found))
(error "Library file \"%s\" not found." library))))定义此命令后,您可以通过键入Mx find-library file Enter
Enter来访问任何库的实现。如果您像作者一样经常使用它,您也可能会发现它值得绑定到按键序列。我们不会详细讨论这个函数的工作原理,因为它比本章更深入一些,但如果您对某些函数的作用感到好奇,可以将光标放在 Lisp 缓冲区中的函数名称上并使用帮助系统的“描述功能”( Ch f ) 功能来获取有关它的更多信息。libraryname
Once this command is defined, you can visit any
library's implementation by typing M-x find-library file Enter
libraryname
Enter. If you use it as often as this author
does, you too may find it worth binding to a key sequence. We
won't present a detailed discussion of how this
function works because it goes a bit deeper than this chapter, but if
you're curious about what some of the functions do,
you can put your cursor in the function name in a Lisp buffer and use
the Help system's "Describe
function" (C-h f)
feature to get more information about it.
如果您发现大多数时候当您请求库时,您最终会得到一个包含大量神秘数字代码且没有注释的文件,请检查文件名是否以.elc.如果这通常是您最终得到的结果,则意味着您的系统上仅安装了库的字节编译版本(请参阅本章末尾的讨论)。询问您的系统管理员是否可以安装源代码;这是能够学习和调整 Emacs Lisp 环境的重要部分。
If you find that most of the time when you ask for a library, you end
up with a file containing a lot of cryptic numeric codes and no
comments, check if the filename ends in .elc. If
that is usually what you end up with, it means that only the
byte-compiled versions of the libraries (see the discussion at the
end of this chapter) have been installed on your system. Ask your
system administrator if you can get the source installed;
that's an important part of being able to learn and
tweak the Emacs Lisp environment.
函数re-search-forward、 re-search-backward、Replace-regexp、query-replace-regexp、highlight-regexp、isearch-forward-regexp和isearch-backward-regexp都是用户的 使用正则表达式的命令,它们都可以在 Lisp 代码中使用(尽管很难想象在 Lisp 代码中使用增量搜索)。本章后面有关自定义主要模式的部分包含一个使用re-search-forward的示例函数。要查找使用正则表达式的其他命令,您可以使用“apropos”帮助功能(Ch a regexp Enter)。
The functions re-search-forward, re-search-backward, replace-regexp, query-replace-regexp, highlight-regexp, isearch-forward-regexp, and isearch-backward-regexp are all user commands that use regular expressions, and they can all be used within Lisp code (though it is hard to imagine incremental search being used within Lisp code). The section on customizing major modes later in this chapter contains an example function that uses re-search-forward. To find other commands that use regexps you can use the "apropos" help feature (C-h a regexp Enter).
其他此类功能不能作为用户命令使用。也许使用最广泛的一种是“看着”。该函数接受正则表达式参数并执行以下操作:t如果 point 之后的文本与正则表达式匹配(nil否则),则返回
;如果存在匹配,它会保存周围的棋子\\(以
\\)供将来使用,如前所述。函数
string-match类似:它接受两个参数,一个正则表达式和一个字符串。它返回与正则表达式匹配的字符串部分的起始索引,或者
nil如果没有匹配则返回。
Other such functions aren't available as user
commands. Perhaps the most widely used one is looking-at. This function takes a regular
expression argument and does the following: it returns
t if the text after point matches the regular
expression (nil otherwise); if there was a match,
it saves the pieces surrounded by \\( and
\\) for future use, as seen earlier. The function
string-match is similar: it takes
two arguments, a regexp and a string. It returns the starting index
of the portion of the string that matches the regexp, or
nil if there is no match.
函数match-beginning和
match-end可用于检索匹配字符串的已保存部分。每个都将匹配表达式的编号作为参数(如在
\\
nReplace -regexp替换字符串中),并返回缓冲区中标记匹配表达式的开始(对于
match-beginning)或结束(对于
match-end)的字符位置细绳。使用参数0,返回标记与正则表达式匹配的整个字符串的开始/结束的字符位置。
The functions match-beginning and
match-end can be used to retrieve
the saved portions of the matched string. Each takes as an argument
the number of the matched expression (as in
\\
n in replace-regexp replace strings) and returns
the character position in the buffer that marks the beginning (for
match-beginning) or end (for
match-end) of the matched string.
With the argument 0, the character position that
marks the beginning/end of the entire string matched by the regular
expression is returned.
还需要两个函数才能使上述内容有用:我们需要知道如何将缓冲区中的文本转换为字符串。没问题: buffer-string将整个缓冲区作为字符串返回;buffer-substring 采用两个整数参数,标记所需子字符串的开始和结束位置,并返回子字符串。
Two more functions are needed to make the above useful: we need to know how to convert the text in a buffer to a string. No problem: buffer-string returns the entire buffer as a string; buffer-substring takes two integer arguments, marking the beginning and end positions of the substring desired, and returns the substring.
使用这些函数,我们可以编写一些 Lisp 代码,该代码返回一个字符串,其中包含与第 n个带括号的子表达式匹配的缓冲区部分:
With these functions, we can write a bit of Lisp code that returns a string containing the portion of the buffer that matches the nth parenthesized subexpression:
(缓冲区子字符串(匹配开始n(匹配结束n)))
(buffer-substring (match-beginningn(match-endn)))
事实上,这种结构使用得非常频繁,以至于 Emacs 有一个内置函数match-string来充当简写;返回与前面示例相同的结果。(match-string
n
)
In fact, this construct is used so often that Emacs has a built-in
function, match-string, that acts as
a shorthand; (match-string
n
) returns the same
result as in the previous example.
应该通过一个示例来展示此功能的工作原理。假设您正在编写解析编译器错误消息的 Lisp 代码,如我们前面的示例所示。您的代码将遍历compilation-error-regexp-alist中的每个元素,检查缓冲区中的文本是否与正则表达式匹配。如果匹配,您的代码需要提取文件名和行号,访问该文件,然后转到行号。
An example should show how this capability works. Assume you are writing the Lisp code that parses compiler error messages, as in our previous example. Your code goes through each element in compilation-error-regexp-alist, checking if the text in a buffer matches the regular expression. If it matches, your code needs to extract the filename and the line number, visit the file, and go to the line number.
虽然遍历列表中每个元素的代码超出了我们目前所学的范围,但例程基本上如下所示:
Although the code for going down each element in the list is beyond what we have learned so far, the routine basically looks like this:
for each element in编译错误正则表达式列表 (让((正则表达式) (文件子表达式)the regexp in the elementthe number of the filename subexpression(行子表达式the number of the line number subexpression)) (如果(查看正则表达式) (let ((文件名(匹配字符串文件子表达式)) (linenum (匹配字符串 line-subexp))) (查找文件其他窗口文件名) (转到行linenum)) (otherwise, try the next element in the list)))
for each element incompilation-error-regexp-alist (let ((regexpthe regexp in the element) (file-subexpthe number of the filename subexpression) (line-subexpthe number of the line number subexpression)) (if (looking-at regexp) (let ((filename (match-string file-subexp)) (linenum (match-string line-subexp))) (find-file-other-window filename) (goto-line linenum)) (otherwise, try the next element in the list)))
第二个let从缓冲区中从与第 -th 子表达式匹配的开头到结尾提取文件名
file-subexp,并以类似的方式从 -th 子表达式中提取行号line-subexp(并将其从字符串转换为数字)。然后代码访问该文件(在另一个窗口中,与错误消息缓冲区不同)并转到发生错误的行号。
The second let extracts the filename
from the buffer from the beginning to the end of the match to the
file-subexp-th subexpression, and it extracts the
line number similarly from the line-subexp-th
subexpression (and converts it from a string to a number). Then the
code visits the file (in another window, not the same one as the
error message buffer) and goes to the line number where the error
occurred.
本章后面的计算器模式代码包含一些其他的Looking-at、 match-beginning和match-end示例。
The code for the calculator mode later in this chapter contains a few other examples of looking-at, match-beginning, and match-end.
Emacs 包含 数百个内置函数可能对您编写 Lisp 代码有用。然而,找到针对特定目的使用哪一个并不是那么困难。
Emacs contains hundreds of built-in functions that may be of use to you in writing Lisp code. Yet finding which one to use for a given purpose is not so hard.
首先要认识到的是,您经常需要使用已经可以作为键盘命令访问的功能。您可以通过Ch k(用于描述键)命令找出它们的函数名称来使用它们
(请参阅第 14 章)。这提供了命令的完整文档,而不是
Ch c(用于描述密钥简短),后者仅提供命令的名称。请注意:在某些情况下,一些常见的键盘命令在用作 Lisp 函数时需要参数。一个例子是forward-word;要获得相当于键入
Mf的效果,您必须使用
(forward-word 1).
The first thing to realize is that you will often need to use
functions that are already accessible as keyboard commands. You can
use these by finding out what their function names are via the
C-h k (for describe-key) command (see Chapter 14). This gives the
command's full documentation, as opposed to
C-h c (for describe-key-briefly), which gives only the
command's name. Be careful: in a few cases, some
common keyboard commands require an argument when used as Lisp
functions. An example is forward-word; to get the equivalent of typing
M-f, you have to use
(forward-word 1).
另一个获得适合工作的功能的强大工具是command-apropos ( Ch a ) 帮助功能。给定正则表达式,此帮助函数会搜索与其匹配的所有命令,并在窗口中显示它们的键绑定(如果有)和文档
*Help*。如果您试图找到执行某些“基本”操作的命令,这可能会很有帮助。例如,如果您想了解对单词进行操作的命令,请键入Ch
a,然后键入
word,您将看到大约十几个与单词有关的命令的文档。
Another powerful tool for getting the right function for the job is
the command-apropos (C-h a) help function. Given a regular
expression, this help function searches for all commands that match
it and display their key bindings (if any) and documentation in a
*Help* window. This can be a great help if you are
trying to find a command that does a certain
"basic" thing. For example, if you
want to know about commands that operate on words, type C-h
a followed by
word, and you will see documentation on
about a dozen and a half commands having to do with words.
command-apropos的局限性
在于它仅提供有关可用作键盘命令的功能的信息。更强大的是apropos,它无法通过任何帮助键访问(您必须输入Mx apropos Enter)。给定一个正则表达式,apropos显示与其匹配的所有函数、变量和其他符号。但请注意:如果将 apropos 与足够通用的概念(例如 )一起使用,则apropos可能需要很长时间才能运行,并且可能会生成很长的列表buffer。
The limitation with command-apropos
is that it gives information only on functions that can be used as
keyboard commands. Even more powerful is apropos, which is not accessible via any of
the help keys (you must type M-x apropos
Enter). Given a regular expression, apropos displays all functions, variables, and
other symbols that match it. Be warned, though: apropos can take a long time to run and can
generate very long lists if you use it with a general enough concept
(such as buffer).
您应该能够对少量精选的关键字使用apropos命令并找到您需要的函数。因为,如果一个函数看起来足够通用和基本,那么 Emacs 很有可能内置它。
You should be able to use the apropos commands on a small number of well-chosen keywords and find the function(s) you need. Because, if a function seems general and basic enough, the chances are excellent that Emacs has it built-in.
找到您感兴趣的函数后,您可能会发现apropos
打印的文档没有为您提供有关该函数的功能、其参数、如何使用它等的足够信息。此时最好的做法是搜索 Emacs 的 Lisp 源代码以获取该函数的使用示例。本章前面的“示例宝库”提供了查找 Emacs 从中加载库的目录名称的方法,以及在知道库名称后查看库的简单方法。要搜索库文件的内容,您需要使用
grep或其他一些搜索工具来查找示例,然后编辑找到的文件以查看周围的上下文。如果您雄心勃勃,您可以将我们到目前为止讨论的示例和概念放在一起,编写find-library-file命令的扩展,用于搜索
加载路径上每个目录中的库文件的内容!尽管 Emacs 的大多数内置 Lisp 代码都没有详细记录,但它提供的函数使用示例应该会有所帮助,甚至可能为您提供有关自己的函数的想法。
After you find the function you are interested in, you may find that
the documentation that apropos
prints does not give you enough information about what the function
does, its arguments, how to use it, or whatever. The best thing to do
at this point is to search Emacs's Lisp source code
for examples of the function's use.
"A Treasure Trove of Examples"
earlier in this chapter provides ways of finding out the names of
directories Emacs loads libraries from and an easy way of looking at
a library once you know its name. To search the contents of the
library files you'll need to use
grep or some other search facility to find
examples, then edit the files found to look at the surrounding
context. If you're ambitious you could put together
the examples and concepts we've discussed so far to
write an extension of the find-library-file command that searches the
contents of the library files in each directory
on the load path! Although most of Emacs's built-in
Lisp code is not profusely documented, the examples of function use
that it provides should be helpful—and may even give you ideas
for your own functions.
到目前为止,您应该已经拥有一个 Emacs Lisp 框架,足以编写许多有用的 Emacs 命令。我们已经介绍了各种函数的示例,包括 Lisp 原语和内置 Emacs 函数。您应该能够从本章中给出的内容以及诸如刚刚提供的帮助技术中推断出许多其他内容。换句话说,您正在成为一名流利的 Emacs Lisp 程序员。要测试自己,请从count-words-buffer的代码开始 ,并尝试编写以下函数:
By now, you should have a framework of Emacs Lisp that should be sufficient for writing many useful Emacs commands. We have covered examples of various kinds of functions, both Lisp primitives and built-in Emacs functions. You should be able to extrapolate many others from the ones given in this chapter along with help techniques such as those just provided. In other words, you are well on your way to becoming a fluent Emacs Lisp programmer. To test yourself, start with the code for count-words-buffer and try writing the following functions:
打印缓冲区中的行数。
Print the number of lines in the buffer.
打印一个区域中的单词数。
Print the number of words in a region.
打印当前所在线点的编号。
Print the number of the line point is currently on.
[ 6 ] Emacs 使用 ASCII 代码(在大多数机器上)来构建范围,但您不应该依赖这一事实;最好坚持使用可靠的东西,例如全小写或全大写字母子集或数字[0-9],并避免潜在的不可移植项目,例如[Az]和涉及标点符号的范围。
[6] Emacs uses ASCII codes (on most machines) to build ranges, but you shouldn't depend on this fact; it is better to stick to dependable things, like all-lowercase or all-uppercase alphabet subsets or [0-9] for digits, and avoid potentially nonportable items, like [A-z] and ranges involving punctuation characters.
你可能开始 了解如何以真正强大的方式将所有这些工具组合在一起。本章其余部分的大部分内容都包含为 Emacs 构建相对真实且有用的新功能的示例。您可以将它们用作如何构建自己的学习工具,并且您可以在自己的日常工作中按原样使用它们,或者稍作调整。
You're probably starting to see how all these tools can be put together in really powerful ways. Most of the rest of the chapter consists of examples of building relatively real and useful new features for Emacs. You can use them as learning tools for how to build your own, and you may be able to use them as-is, or with a little tweaking, in your own daily work.
我们将要看到的示例是一位作者十多年前开发的,旨在帮助解决开发项目中创建新文件的乏味问题,在开发项目中始终需要一定数量的结构和标准文档。许多编码和写作项目都有这个特点;每个文件都需要一些样板,但需要根据文件的详细信息进行调整。事实证明,Emacs 非常适合自动化大量繁琐的工作,从那时起,这个模板系统就被大量使用。
The example we're about to look at is something that one of the authors developed over a decade ago to help with the tedium of creating new files in development projects where a certain amount of structure and standard documentation were always needed. Many coding and writing projects have this characteristic; each file needs some boilerplate, but it needs to be adjusted to the details of the file. Emacs turned out to be very much up to the task of automating a lot of the drudge work, and this template system has been heavily used ever since.
此示例中的大部分代码对您来说应该已经有意义。下一节将更全面地解释有关对主要模式进行编程的几个方面。特别是,不要太担心“钩子”函数或funcall到底是什么。现在只要知道file-not-found-hook允许我们在用户使用find-file打开一个尚不存在的文件时运行代码就足够了(正是我们想要提供我们的文件的时间)模板服务)。
Most of the code in this example should already make sense to you. A couple of aspects that will be explained more thoroughly in the next section about programming a major mode. In particular, don't worry too much yet about exactly what a "hook" function is, or funcall. For now it's sufficient to know that the file-not-found-hook allows us to run code when the user uses find-file to open a file that doesn't exist yet (exactly the time at which we'd like to offer our template services).
在开始编写代码之前,值得看一下实际的示例。您可以通过在以下位置 创建一个名为file-template-java 的文件来设置模板 Java 项目目录层次结构的顶层,包含类似于示例 11-2中所示的代码。
Before launching into the code, it's worth looking at an example of it in action. You'd set up your template by creating a file named file-template-java at the top level of a Java project directory hierarchy, containing something like the code shown in Example 11-2.
例11-2。文件模板java
Example 11-2. file-template-java
/* %文件名%
* 创建于%date%
*
* (c) 2004 MyCorp 等。
*/
%包裹%
导入 org.apache.log4j.Logger;
/**
* [文档在这里!]
*
* @作者%作者%
* @version $Id: ch11.xml,v 1.4 2004/12/17 16:10:05 kend Exp $
*
**/
公共类%class%{
/**
* 提供对该类的 CVS 版本的访问。
**/
公共静态最终字符串版本=
"$Id: ch11.xml,v 1.4 2004/12/17 16:10:05 kend Exp $";
/**
* 提供调试的分级控制和配置
* 类包结构。
**/
私有静态记录器日志=
Logger.getLogger(%class%.class);
}/* %filename%
* Created on %date%
*
* (c) 2004 MyCorp, etc. etc.
*/
%package%
import org.apache.log4j.Logger;
/**
* [Documentation Here!]
*
* @author %author%
* @version $Id: ch11.xml,v 1.4 2004/12/17 16:10:05 kend Exp $
*
**/
public class %class% {
/**
* Provides access to the CVS version of this class.
**/
public static final String VERSION =
"$Id: ch11.xml,v 1.4 2004/12/17 16:10:05 kend Exp $";
/**
* Provides hierarchical control and configuration of debugging via
* class package structure.
**/
private static Logger log =
Logger.getLogger(%class%.class);
}示例 11-3中所示的模板系统会导致尝试在此项目层次结构中查找不存在的 Java 源文件(例如,通过Cx Cf src/com/mycorp/util/FooManager.javaStart with template file?
(y or
n) ),从而导致迷你缓冲区中出现提示,如果您回答y,您将看到
FooManager.java缓冲区以中的内容开始
以下示例。
The template system shown in Example 11-3 causes an
attempt to find a nonexistent Java source file within this project
hierarchy (for example, via C-x C-f
src/com/mycorp/util/FooManager.java) to result in the
prompt Start with template file?
(y or
n) in the minibuffer, and if you answer y, you'll see your
FooManager.java buffer start out with contents in
the
following example.
例11-3。 FooManager.java
Example 11-3. FooManager.java
/* FooManager.java
* 创建于 2003 年 11 月 9 日星期日 20:56:12
*
* (c) 2004 MyCorp 等。
*/
包 com.mycorp.util;
导入 org.apache.log4j.Logger;
/**
* [文档在这里!]
*
* @作者吉姆·埃利奥特
* @version $Id: ch11.xml,v 1.4 2004/12/17 16:10:05 kend Exp $
*
**/
公共类 FooManager {
/**
* 提供对该类的 CVS 版本的访问。
**/
公共静态最终字符串版本=
"$Id: ch11.xml,v 1.4 2004/12/17 16:10:05 kend Exp $";
/**
* 提供调试的分级控制和配置
* 类包结构。
**/
私有静态记录器日志=
Logger.getLogger(FooManager.class);
}/* FooManager.java
* Created on Sun Nov 9 20:56:12 2003
*
* (c) 2004 MyCorp, etc. etc.
*/
package com.mycorp.util;
import org.apache.log4j.Logger;
/**
* [Documentation Here!]
*
* @author Jim Elliott
* @version $Id: ch11.xml,v 1.4 2004/12/17 16:10:05 kend Exp $
*
**/
public class FooManager {
/**
* Provides access to the CVS version of this class.
**/
public static final String VERSION =
"$Id: ch11.xml,v 1.4 2004/12/17 16:10:05 kend Exp $";
/**
* Provides hierarchical control and configuration of debugging via
* class package structure.
**/
private static Logger log =
Logger.getLogger(FooManager.class);
}该模板用于使用标准项目头注释和基本 Java 类框架填充缓冲区,并填充适当的上下文值(例如当前时间、创建文件的人、文件和类名称等) )。甚至 Java
package语句也是通过检查创建源文件的目录路径来推断的。对于使用优秀系统向其 Java 项目添加日志记录和调试的任何人来说,该
Logger声明看起来都很熟悉。 log4j(“”字符串中的奇怪版本号$Id由 CVS 版本控制系统管理,并在签入时更新为正确的文件和版本信息。这个主题将在第 12 章中讨论。)
The template has been used to populate the buffer with the standard
project header comments and a basic Java class skeleton, with proper
contextual values filled in (such as the current time, the person
creating the file, the file and class name, and so on). Even the Java
package statement has been inferred by examining
the directory path in which the source file is being created. The
Logger declaration will look familiar to anyone
who uses the excellent log4j system to add
logging and debugging to their Java projects. (The strange version
numbers in "$Id"
strings are managed by the CVS version control system and will be
updated to the proper file and version information when
it's checked in. This topic is discussed in Chapter 12.)
为了实现这一点,模板系统需要能够执行以下操作:
To make this work, the template system needs to be able to do a couple of things:
拦截用户查找不存在文件的尝试。
Intercept the user's attempt to find a nonexistent file.
检查父目录中是否有合适的模板文件。
Check whether there is an appropriate template file somewhere in a parent directory.
如果是这样,请提供使用它,并用模板文件的内容填充缓冲区。
If so, offer to use it, and populate the buffer with the contents of the template file.
扫描模板文件中的特殊占位符(例如
%filename%)并将其替换为有关正在创建的文件的信息。
Scan the template file for special placeholders (such as
%filename%) and replace them with information
about the file being created.
让我们看看使这一切发生的源代码! (与往常一样,如果您不想自己键入例 11-4中列出的代码,您可以从本书的网站下载它。[ 7 ])
Let's look at the source code that makes this all happen! (As always, if you don't want to type the code listed in Example 11-4 yourself, you can download it from this book's web site.[7])
例11-4。模板.el
Example 11-4. template.el
;;;;;;;;;;;;;;;;;;;;;;;;;;;; -*- 模式:Emacs-Lisp -*- ;;;;;;;;;;;;;;;;;;;;;;;;;
;; template.el --- 为文件生成智能骨架模板的例程。
(defvar 模板文件名“文件模板”
“*查找文件请求失败时要查找的文件的名称。如果
具有此变量指定名称的文件存在,建议将其用作
用于创建新文件的模板。您还可以拥有特定于模式的
模板通过将“-扩展名”附加到该文件名,例如 Java 特定的
模板将是 file-template-java。”)
(defvar 模板替换列表
'((“%文件名%”。(lambda ( )
(文件名非目录(缓冲区文件名))))
(“%creator%”。用户全名)
(“%author%”。用户全名)
("%date%" .当前时间字符串)
(“%once%”。(lambda () (模板插入包含一次)))
("%package%" .(lambda () (template-insert-java-package)))
("%class%" .(lambda ( ) (模板插入类名)))
)
“指定加载时执行哪些替换的列表
模板文件。每个列表元素由一个字符串组成,该字符串是目标
如果在模板中找到它并与函数配对,则将其替换,
调用它来生成字符串的替换值。”)
(defun 查找模板文件 ( )
“在当前目录及其父目录中搜索匹配的文件
为模板文件配置的名称。第一个这样的名字
返回找到的可读文件,允许分层模板
配置。与文件具有相同扩展名的模板文件
正在加载(使用“-”而不是“.”作为模板文件的
分隔符,以避免混淆其他软件)将优先
通过无扩展的通用模板。”
(let ((路径(文件名目录(缓冲区文件名)))
(ext (文件名扩展名(缓冲区文件名)))
尝试结果)
(while (and (不是结果) (> (路径长度) 0))
(setq尝试(连接路径模板文件名“-”ext))
(如果(文件可读-p尝试)
(setq 结果尝试)
(setq尝试(连接路径模板文件名))
(如果(文件可读-p尝试)
(setq 结果尝试)
(setq 路径 (if (字符串等于路径“/”)
””
(文件名目录(子字符串路径0 -1)))))))
结果))
(defun 模板文件未找到钩子 ( )
“当 find-file 命令无法找到指定的文件时调用
当前目录中的文件。看看主动提出启动是否有意义
基于模板。”
(条件情况为零
(如果(和(查找模板文件)
(y-or-np“从模板文件开始?”))
(progn (缓冲区-禁用-撤消)
(插入文件(查找模板文件))
(goto-char (点-分钟))
;;神奇地进行变量替换
(让((列表模板替换列表))
(而列表
(goto-char (点-分钟))
(替换字符串(汽车(汽车列表))
(funcall (cdr (汽车列表)))
零)
(setq the-list (cdr the-list))))
(goto-char (点-分钟))
(缓冲区-启用-撤消)
(设置缓冲区修改-p nil)))
;;这是条件情况的一部分;它抓住了这样的情况
;;用户已经点击 Cg 来中止查找文件(因为他们意识到
;;他们不是这个意思)并删除已经存在的缓冲区
;;被创建为与该文件一起使用,因为否则它将变成
;;他们甚至可能不知道神秘的混乱。
('退出(kill-buffer(当前缓冲区))
(信号“退出”退出))))
;安装上面的例程
(或(memq'模板文件未找到钩子查找文件未找到钩子)
(setq find-file-not-found-hooks
(附加 find-file-not-found-hooks '(template-file-not-found-hook)))
)
(defun 模板插入包含一次 ( )
“返回预处理器指令,以便包含该文件
在包含它的编译过程中仅一次
任意次数。”
(let ((名称(文件名-非目录(缓冲区文件名)))
基本名称)
(if (字符串匹配“.h$”名称)
(程序
(setq basename (upcase (子字符串名称 0 -2)))
(concat "#ifndef _H_" 基本名称 "\n#define _H_" 基本名称
"\n\n\n#endif /* 未定义 _H_" 基本名称 " */\n"))
“”; “else”子句返回一个空字符串。
)))
(defun template-insert-java-package ( )
“根据路径插入适当的 Java 包指令
当前文件名(假设它位于 com、org 或 net
子树)。如果找不到可识别的包路径,则不插入任何内容。”
(let ((名称(文件名目录(缓冲区文件名)))
结果)
(if(字符串匹配“/\\(com\\|org\\|net\\)/.*/$”名称)
(程序
(setq 结果(子串名称(+(匹配开始0)1)
(- (比赛结束 0) 1)))
(while (字符串匹配“/”结果)
(setq result(concat(子串结果0(匹配开始0)))
“。”
(子串结果(匹配结束0)))))
(连接“包”结果“;”))
“”)))
(defun 模板插入类名称 ( )
“插入当前文件中定义的java类的名称,
基于文件名。如果不是 Java 源文件,则不插入任何内容。”
(let ((名称(文件名-非目录(缓冲区文件名))))
(if (字符串匹配“\\(.*\\)\\.java”名称)
(子字符串名称 (匹配开始 1) (匹配结束 1))
“”)))
(提供'模板);;;;;;;;;;;;;;;;;;;;;;;;;;; -*- Mode: Emacs-Lisp -*- ;;;;;;;;;;;;;;;;;;;;;;;;
;; template.el --- Routines for generating smart skeletal templates for files.
(defvar template-file-name "file-template"
"*The name of the file to look for when a find-file request fails. If a
file with the name specified by this variable exists, offer to use it as
a template for creating the new file. You can also have mode-specific
templates by appending \"-extension\" to this filename, e.g. a Java specific
template would be file-template-java.")
(defvar template-replacements-alist
'(("%filename%" . (lambda ( )
(file-name-nondirectory (buffer-file-name))))
("%creator%" . user-full-name)
("%author%" . user-full-name)
("%date%" . current-time-string)
("%once%" . (lambda ( ) (template-insert-include-once)))
("%package%" . (lambda ( ) (template-insert-java-package)))
("%class%" . (lambda ( ) (template-insert-class-name)))
)
"A list which specifies what substitutions to perform upon loading a
template file. Each list element consists of a string, which is the target
to be replaced if it is found in the template, paired with a function,
which is called to generate the replacement value for the string.")
(defun find-template-file ( )
"Searches the current directory and its parents for a file matching
the name configured for template files. The name of the first such
readable file found is returned, allowing for hierarchical template
configuration. A template file with the same extension as the file
being loaded (using a \"-\" instead of a \".\" as the template file's
delimiter, to avoid confusing other software) will take precedence
over an extension-free, generic template."
(let ((path (file-name-directory (buffer-file-name)))
(ext (file-name-extension (buffer-file-name)))
attempt result)
(while (and (not result) (> (length path) 0))
(setq attempt (concat path template-file-name "-" ext))
(if (file-readable-p attempt)
(setq result attempt)
(setq attempt (concat path template-file-name))
(if (file-readable-p attempt)
(setq result attempt)
(setq path (if (string-equal path "/")
""
(file-name-directory (substring path 0 -1)))))))
result))
(defun template-file-not-found-hook ( )
"Called when a find-file command has not been able to find the specified
file in the current directory. Sees if it makes sense to offer to start it
based on a template."
(condition-case nil
(if (and (find-template-file)
(y-or-n-p "Start with template file? "))
(progn (buffer-disable-undo)
(insert-file (find-template-file))
(goto-char (point-min))
;; Magically do the variable substitutions
(let ((the-list template-replacements-alist))
(while the-list
(goto-char (point-min))
(replace-string (car (car the-list))
(funcall (cdr (car the-list)))
nil)
(setq the-list (cdr the-list))))
(goto-char (point-min))
(buffer-enable-undo)
(set-buffer-modified-p nil)))
;; This is part of the condition-case; it catches the situation where
;; the user has hit C-g to abort the find-file (since they realized
;; that they didn't mean it) and deletes the buffer that has already
;; been created to go with that file, since it will otherwise become
;; mysterious clutter they may not even know about.
('quit (kill-buffer (current-buffer))
(signal 'quit "Quit"))))
; Install the above routine
(or (memq 'template-file-not-found-hook find-file-not-found-hooks)
(setq find-file-not-found-hooks
(append find-file-not-found-hooks '(template-file-not-found-hook)))
)
(defun template-insert-include-once ( )
"Returns preprocessor directives such that the file will be included
only once during a compilation process which includes it an
abitrary number of times."
(let ((name (file-name-nondirectory (buffer-file-name)))
basename)
(if (string-match ".h$" name)
(progn
(setq basename (upcase (substring name 0 -2)))
(concat "#ifndef _H_" basename "\n#define _H_" basename
"\n\n\n#endif /* not defined _H_" basename " */\n"))
"" ; the "else" clause, returns an empty string.
)))
(defun template-insert-java-package ( )
"Inserts an appropriate Java package directive based on the path to
the current file name (assuming that it is in the com, org or net
subtree). If no recognizable package path is found, inserts nothing."
(let ((name (file-name-directory (buffer-file-name)))
result)
(if (string-match "/\\(com\\|org\\|net\\)/.*/$" name)
(progn
(setq result (substring name (+ (match-beginning 0) 1)
(- (match-end 0) 1)))
(while (string-match "/" result)
(setq result (concat (substring result 0 (match-beginning 0))
"."
(substring result (match-end 0)))))
(concat "package " result ";"))
"")))
(defun template-insert-class-name ( )
"Inserts the name of the java class being defined in the current file,
based on the file name. If not a Java source file, inserts nothing."
(let ((name (file-name-nondirectory (buffer-file-name))))
(if (string-match "\\(.*\\)\\.java" name)
(substring name (match-beginning 1) (match-end 1))
"")))
(provide 'template)您会注意到这段代码大量使用了正则表达式工具,这并不奇怪。第一部分设置一些配置模板系统操作的变量。template-file-name 确定用于搜索模板的文件名(或前缀);file-template的默认值可能没问题。template-replacements-alist设置标准占位符,以及将它们替换为适当值的机制。向此列表添加条目是扩展系统的一种方法。每个条目都包含要替换的占位符,后跟要执行以生成其替换内容的 Lisp 函数。这个函数可以存储在列表中并在适当的时候执行,这是 Lisp 的一大优点,并将在下一节的计算器模式示例中更深入地讨论。支持的占位符有:
You'll notice that this code makes heavy use of the regular expression facilities, which is no surprise. The first section sets up some variables that configure the operation of the template system. template-file-name determines the file name (or prefix) that is used to search for templates; the default value of file-template is probably fine. template-replacements-alist sets up the standard placeholders, and the mechanism by which they get replaced by appropriate values. Adding entries to this list is one way to extend the system. Each entry consists of the placeholder to be replaced, followed by the Lisp function to be executed to produce its replacement. The way this function can be stored in a list and executed when appropriate later is one of the great things about Lisp and is discussed in more depth in the calculator mode example in the next section. The placeholders supported are:
%filename%
%filename%
被正在创建的文件的名称替换。
Gets replaced by the name of the file being created.
%creator%,%author%
%creator%, %author%
这些是同义词;两者都被创建文件的用户名替换。
These are synonyms; both get replaced by the name of the user creating the file.
%date%
%date%
变成创建文件时的当前日期和时间。
Turns into the current date and time when the file is created.
%once%
%once%
扩展为 C 预处理器的样板代码,使头文件仅包含其自身一次,即使它已被其他头文件包含多次。 (此类事情已在 Objective C 和 Java 等更现代的环境中得到处理,但在使用传统 C 编译器时仍然很方便。)
Expands into boilerplate code for the C preprocessor to cause a header file to include itself only once, even if it's been included multiple times by other header files. (This sort of thing has been taken care of in more modern environments like Objective C and Java but can still be handy when working with traditional C compilers.)
%package%
%package%
由包含正在创建的文件的 Java 包替换(假设该文件是 Java 类)。该包是通过检查放置文件的目录结构来确定的。
Is replaced by the Java package which contains the file being created (assuming the file is a Java class). This package is determined by examining the directory structure in which the file is being placed.
%class%
%class%
成为文件中定义的 Java 类的名称(假设它是 Java 源文件)。
Becomes the name of the Java class being defined in the file, assuming it's a Java source file.
第一个函数find-template-file负责搜索正在创建的文件上方的目录层次结构,查找具有正确名称的文件以被视为文件模板(如果template-file-name已保留为默认值)值,这会查找名为file-template或 file-template-ext的文件, 其中ext 是正在创建的文件名末尾的扩展名)。它只是不断地从它正在查找的路径中删除最后一个目录,从新文件的位置开始,并查看是否可以读取当前目录中具有这些名称之一的文件,直到用完目录。
The first function, find-template-file, is responsible for searching the directory hierarchy above the file being created, looking for a file with the right name to be considered a file template (if template-file-name has been left at its default value, this looks for either a file named file-template or file-template-ext where ext is the extension at the end of the name of the file being created). It just keeps lopping the last directory off the path in which it's looking, starting with the location of the new file, and seeing if it can read a file with one of those names in the current directory, until it runs out of directories.
函数template-file-not-found-hook是模板系统的“主程序”。它“挂钩”到正常的 Emacs查找文件进程,并在find-file找不到用户请求的文件时调用 (换句话说,正在创建一个新文件)。它使用条件情况(一种类似于 C++ 和 Java 中的异常处理的机制)来确保如果用户取消填写模板文件的过程,它有机会自行清理。它检查是否可以找到模板文件,询问用户是否要使用它,并且(如果愿意)将其加载到新缓冲区中并执行占位符替换。有关使替换起作用的列表操作和funcall代码的说明,请阅读下一节中对计算器模式的讨论。最后,它跳转到新缓冲区的开头并将其标记为未更改(因为,就用户而言,这是一个全新的缓冲区,他们尚未花费任何精力)。
The function template-file-not-found-hook is the "main program" of the template system. It gets "hooked in" to the normal Emacs find-file process, and called whenever find-file doesn't find the file the user asked for (in other words, a new file is being created). It uses condition-case (a mechanism similar to exception handling in C++ and Java) to make sure it gets a chance to clean up after itself if the user cancels the process of filling in the template file. It checks whether the template file can be found, asks users if they want to use it, and (if they do) loads it into the new buffer and performs the placeholder substitutions. For an explanation of the list manipulation and funcall code that makes the substitutions work, read the discussion of Calculator mode in the next section. Finally, it jumps to the beginning of the new buffer and marks it as unchanged (because, as far as users are concerned, it's a brand new buffer on which they've not yet had to expend any effort).
紧接在函数定义之后的是将其挂接到查找文件机制的代码块 。 file -not-found-hooks 是一个变量,Emacs 使用它来跟踪未找到所请求的文件时要执行的操作。 (通过“挂钩”为您提供改变或增强正常行为的机会是 Emacs 的一个奇妙特性,本章后面的计算器模式示例将对此进行更深入的讨论。)我们的代码进行检查以确保它尚未挂钩(因此如果您在 Emacs 会话期间重新加载库文件,则最终不会让它运行两次或更多次),然后在列表末尾安装我们的钩子(如果它不存在)。
Immediately after the function definition is the chunk of code that hooks it into the find-file mechanism. The file-not-found-hooks is a variable that Emacs uses to keep track of things to do when a requested file is not found. (Giving you opportunities to change or enhance normal behavior through "hooks" is a wonderful trait of Emacs that is discussed in more depth following the Calculator mode example later in this chapter.) Our code checks to make sure it's not already hooked up (so you don't end up having it run twice or more if you re-load the library file during an Emacs session), and then installs our hook at the end of the list if it's not there.
文件的其余部分是辅助函数,用于处理更复杂的占位符。template-insert-java-package计算出应替换 的值%package%,而
template-insert-class-name计算出替换 的 Java 类名%class%。
The rest of the file is helper functions to handle the more complex
placeholders. template-insert-java-package figures out the
value that should replace %package%, while
template-insert-class-name figures
out the Java class name that replaces %class%.
文件中的最后一个函数调用(provide
'template)记录了名为“template”的“feature”已成功加载的事实。 Provide函数与require配合使用,允许库仅加载一次。当执行函数
'时,Emacs 会检查是否曾经提供过“模板”功能。如果有,则不执行任何操作,否则,调用load-library来加载它。让您的库支持此机制是一个很好的做法,这样其他库就可以通过require机制优雅且高效地使用它们。您将在整个 Emacs 库源代码中找到这种模式。(requiretemplate)
The last function call in the file, (provide
'template), records the fact that a
"feature" named
"template" has been loaded
successfully. The provide function
works with require to allow
libraries to be loaded just once. When the function
(require 'template) is
executed, Emacs checks whether the feature
"template" has ever been provided.
If it has, it does nothing, otherwise, it calls load-library to load it. It's
a good practice to have your libraries support this mechanism, so
that they can be gracefully and efficiently used by other libraries
through the require mechanism.
You'll find this pattern throughout the Emacs
library sources.
[ 7 ]出于空间和清晰度的原因,本示例中提供的版本已被简化。完整版本还可以下载,它增加了插入函数定义模板和处理模板文件中任意 Emacs Lisp 函数的功能。
[7] The version presented in this example is simplified for reasons of space and clarity. The full version, which adds the ability to insert templates for function definitions and process arbitrary Emacs Lisp functions within template files, is also available for download.
当你感到舒服之后 使用 Emacs Lisp 编程,您可能会发现您希望 Emacs 做的“额外的小事情”采用了主模式的形式。在前面的章节中,我们介绍了文本输入、文字处理器输入和编程语言的主要模式。其中许多模式的编程都相当复杂,因此我们将提供一个主要模式的简单示例,您可以从中学习编写自己的模式所需的概念。然后,在下一节中,您将了解如何在不更改任何实现它们的 Lisp 代码的情况下自定义现有的主要模式。
After you get comfortable with Emacs Lisp programming, you may find that that "little extra something" you want Emacs to do takes the form of a major mode. In previous chapters, we covered major modes for text entry, word processor input, and programming languages. Many of these modes are quite complicated to program, so we'll provide a simple example of a major mode, from which you can learn the concepts needed to program your own. Then, in the following section, you will learn how you can customize existing major modes without changing any of the Lisp code that implements them.
我们将开发计算器模式,这是计算器的主要模式,如果您使用过 Unix dc(桌面计算器)命令,您会熟悉其功能。它是 Hewlett-Packard 流行的逆波兰式(基于堆栈的)计算器。在解释了主要模式的一些主要组成部分和计算器模式的一些有趣功能之后,我们将给出该模式的完整 Lisp 代码。
We'll develop Calculator mode, a major mode for a calculator whose functionality will be familiar to you if you have used the Unix dc (desk calculator) command. It is a Reverse Polish (stack-based) calculator of the type made popular by Hewlett-Packard. After explaining some of the principal components of major modes and some interesting features of the calculator mode, we will give the mode's complete Lisp code.
一个主要模式有多种 将其集成到 Emacs 中的组件。有些是:
A major mode has various components that integrate it into Emacs. Some are:
The symbol that is the name of the function that implements the mode
出现在模式行括号内的模式名称
The name of the mode that appears in the mode line in parentheses
定义模式下命令的键绑定的
本地keymap
The local
keymap that
defines key bindings for commands in the mode
仅在该模式的 Lisp 代码中已知的变量和常量
Variables and constants known only within the Lisp code for the mode
该模式可能使用的特殊缓冲区
The special buffer the mode may use
让我们按顺序处理这些。模式符号是通过将实现模式的函数名称分配给全局变量major-mode来设置的,如下所示:
Let's deal with these in order. The mode symbol is set by assigning the name of the function that implements the mode to the global variable major-mode, as in:
(setq 主模式 '计算模式)
(setq major-mode 'calc-mode)
类似地,模式名称是通过将适当的字符串分配给全局变量来设置的mode-name,如下所示:
Similarly, the mode name is set by assigning an appropriate string to
the global variable mode-name, as in:
(setq 模式名称“计算器”)
(setq mode-name "Calculator")
本地键盘映射是使用第 10 章中讨论的函数定义的。在计算器模式的情况下,只有一个键序列要绑定(Cj),因此我们使用一种特殊形式的 make-keymap命令,称为make-sparse-keymap,它在少量键绑定时效率更高。要将键盘映射用作模式的本地映射,我们调用函数use-local-map,如下所示:
The local keymap is defined using functions discussed in Chapter 10. In the case of the calculator mode, there is only one key sequence to bind (C-j), so we use a special form of the make-keymap command called make-sparse-keymap that is more efficient with a small number of key bindings. To use a keymap as the local map of a mode, we call the function use-local-map, as in:
(使用本地地图计算模式地图)
(use-local-map calc-mode-map)
正如我们刚刚看到的,变量可以通过使用
setq给它们赋值来定义,或者使用
let来定义函数内的局部变量。定义变量的更“官方”方法是defvar
函数,它允许将变量的文档集成到在线帮助工具中,例如Ch v(用于描述变量)。格式如下:
As we just saw, variables can be defined by using
setq to assign a value to them, or by using
let to define local variables within
a function. The more "official" way
to define variables is the defvar
function, which allows documentation for the variable to be
integrated into online help facilities such as C-h v (for describe-variable). The format is the
following:
(定义变量varname initial-value“description of the variable”)
(defvarvarname initial-value"description of the variable")
其变体是defconst,您可以使用它定义常量值(永不改变)。例如:
A variation on this is defconst, with which you
can define constant values (that never change). For example:
(defconst calc-operator-regexp "[-+*/%]" “用于识别运算符的正则表达式。”)
(defconst calc-operator-regexp "[-+*/%]" "Regular expression for recognizing operators.")
定义用于搜索算术运算符的正则表达式。正如您将看到的,我们使用calc-作为我们为计算器模式定义的所有函数、变量和常量的名称的前缀。其他模式使用此约定;例如,C++ 模式下的所有名称都以c++-.使用此约定是一个好主意,因为它有助于避免与 Emacs 中数千个其他函数、变量等发生潜在的名称冲突。
defines the regular expression to be used in searching for arithmetic
operators. As you will see, we use the calc- as a prefix for the names of all
functions, variables, and constants that we define for the calculator
mode. Other modes use this convention; for example, all names in C++
mode begin with c++-. Using this convention is a
good idea because it helps avoid potential name clashes with the
thousands of other functions, variables, and so on in Emacs.
使变量成为模式的本地变量也是可取的,这样它们仅在运行该模式的缓冲区内是已知的。[ 8 ]为此,请使用make-local-variable 函数,如下所示:
Making variables local to the mode is also desirable so that they are known only within a buffer that is running the mode.[8] To do this, use the make-local-variable function, as in:
(make-local-variable 'calc-stack)
(make-local-variable 'calc-stack)
请注意,需要的是变量的名称,而不是其值;因此,变量名前面有一个单引号,将其变成一个符号。
Notice that the name of the variable, not its value, is needed; therefore a single quote precedes the variable name, turning it into a symbol.
最后,各种主要模式使用不附加到文件的特殊缓冲区。例如,Cx Cb(对于list-buffers)命令创建一个名为 的缓冲区*Buffer
List*。要在新窗口中创建缓冲区,请使用
pop-to-buffer函数,如下所示:
Finally, various major modes use special buffers that are not
attached to files. For example, the C-x
C-b (for list-buffers)
command creates a buffer called *Buffer
List*. To create a buffer in a new window, use the
pop-to-buffer function, as in:
(弹出到缓冲区“*Calc*”)
(pop-to-buffer "*Calc*")
pop-to-buffer有几个有用的变体。我们不会在我们的模式示例中使用它们,但它们在其他情况下很方便。
There are a couple of useful variations on pop-to-buffer. We won't use them in our mode example, but they are handy in other circumstances.
与第 4 章中介绍的 Cx b命令相同;也可以与 Lisp 中的缓冲区名称参数一起使用。
Same as the C-x b command covered in Chapter 4; can also be used with a buffer name argument in Lisp.
仅在 Lisp 代码中使用来指定用于编辑的缓冲区;在 Lisp 函数中创建临时“工作”缓冲区的最佳函数。
Used only within Lisp code to designate the buffer used for editing; the best function to use for creating a temporary "work" buffer within a Lisp function.
逆波兰表示法 计算器使用称为堆栈的数据结构。将堆栈视为类似于自助餐厅中弹簧加载的盘子堆栈。当您在 RPN 计算器中输入数字时,您 会将其压入堆栈。当您应用加号或减号等运算符时,会将顶部的两个数字从堆栈中弹出,对它们进行加或减,然后将结果推回到堆栈中。
A Reverse Polish Notation calculator uses a data structure called a stack. Think of a stack as being similar to a spring-loaded dish stack in a cafeteria. When you enter a number into a RPN calculator, you push it onto the stack. When you apply an operator such as plus or minus, you pop the top two numbers off the stack, add or subtract them, and push the result back on the stack.
列表是Lisp 的一个基本概念,对于实现堆栈来说是很自然的。列表是 Lisp 区别于其他编程语言的主要概念。它是一种数据结构,有两部分:头部和 尾部。由于纯粹的历史原因,这些在 Lisp 术语中分别被称为car和 cdr。将这些术语视为“列表中的第一项”和“列表中的其余部分”。当给定列表参数时,函数car和cdr分别返回列表的头部和尾部。[ 9 ]两个函数经常用于创建列表。cons (construct) 有两个参数,分别成为列表的头和尾。list获取元素列表并将它们放入列表中。例如,这个:
The list, a fundamental concept of Lisp, is a natural for implementing stacks. The list is the main concept that sets Lisp apart from other programming languages. It is a data structure that has two parts: the head and tail. These are known in Lisp jargon, for purely historical reasons, as car and cdr respectively. Think of these terms as "the first thing in the list" and "the rest of the list." The functions car and cdr, when given a list argument, return the head and tail of it, respectively.[9] Two functions are often used for making lists. cons (construct) takes two arguments, which become the head and tail of the list respectively. list takes a list of elements and makes them into a list. For example, this:
(列表 2 3 4 5)
(list 2 3 4 5)
列出从 2 到 5 的数字,如下:
makes a list of the numbers from 2 to 5, and this:
(缺点 1(列表 2 3 4 5))
(cons 1 (list 2 3 4 5))
制作一个从 1 到 5 的数字列表。应用于该列表的
car1将返回,而cdr
将返回该列表(2 3 4 5)。
makes a list of the numbers from 1 to 5. car applied to that list would return
1, while cdr
would return the list (2 3 4 5).
这些概念很重要,因为堆栈(例如计算器模式中使用的堆栈)很容易实现为列表。要将 的值压x入堆栈calc-stack,我们可以这样说:
These concepts are important because stacks, such as that used in the
calculator mode, are easily implemented as lists. To push the value
of x onto the stack calc-stack, we can just say this:
(setq 计算堆栈(cons x 计算堆栈))
(setq calc-stack (cons x calc-stack))
如果我们想获取堆栈顶部的值,则以下命令将返回该值:
If we want to get at the value at the top of the stack, the following returns that value:
(汽车计算堆栈)
(car calc-stack)
要从堆栈中弹出顶部值,我们这样说:
To pop the top value off the stack, we say this:
(setq 计算堆栈(cdr 计算堆栈))
(setq calc-stack (cdr calc-stack))
请记住,列表的元素可以是任何内容,包括其他列表。 (这就是为什么列表被称为 递归数据结构。)事实上(准备好混淆了吗?)Lisp 中几乎所有不是原子的东西都是列表。这包括函数,它们基本上是函数名称、参数和要计算的表达式的列表。将函数作为列表的想法很快就会派上用场。
Bear in mind that the elements of a list can be anything, including other lists. (This is why a list is called a recursive data structure.) In fact (ready to be confused?) just about everything in Lisp that is not an atom is a list. This includes functions, which are basically lists of function name, arguments, and expressions to be evaluated. The idea of functions as lists will come in handy very soon.
完整的 Lisp 代码
计算器模式出现在本节末尾;您应该在阅读以下说明时参考它。如果您下载或输入代码,则可以通过输入Mx calc-mode Enter来使用计算器。您将被放入缓冲区
*Calc*。您可以键入一行数字和运算符,然后键入Cj来计算该行。表 11-7列出了计算器模式下的三个命令
The complete Lisp code for the
calculator mode appears at the end of this
section; you should refer to it while reading the following
explanation. If you download or type the code in, you can use the
calculator by typing M-x calc-mode
Enter. You will be put in the buffer
*Calc*. You can type a line of numbers and
operators and then type C-j to
evaluate the line. Table 11-7 lists the three
commands in calculator mode
表 11-7。计算器模式命令
Table 11-7. Calculator mode commands
|
命令 Command |
行动 Action |
|---|---|
|
|
打印堆栈顶部的值。 Print the value at the top of the stack. |
|
|
打印整个堆栈内容。 Print the entire stack contents. |
|
|
清除堆栈。 Clear the stack. |
除了分隔数字之外,不需要空格。例如,输入:
Blank spaces are not necessary, except to separate numbers. For example, typing this:
4 17*6-=
4 17*6-=
随后是Cj,计算 (4 * 17) - 6 并导致打印结果 62。
followed by C-j, evaluates (4 * 17) - 6 and causes the result, 62, to be printed.
计算器模式代码的核心是函数 calc-eval和calc-next-token。 (有关这些,请参阅本节末尾的代码。)calc-eval在计算器模式下 绑定到Cj 。从Cj之前的行的开头开始,它调用calc-next-token来获取该行中的每个 标记(数字、运算符或命令字母)并对其进行评估。
The heart of the code for the calculator mode is the functions calc-eval and calc-next-token. (See the code at the end of this section for these.) calc-eval is bound to C-j in Calculator mode. Starting at the beginning of the line preceding C-j, it calls calc-next-token to grab each token (number, operator, or command letter) in the line and evaluate it.
calc-next-token使用cond构造通过使用正则表达式calc-number-regexp、 calc-operator-regexp和calc-command-regexp来查看该点是否存在数字、运算符或命令字母
。根据匹配的正则表达式,它将变量calc-proc-fun设置为应运行的函数的名称(符号)( calc-push-number、 calc-operate或calc-command),并且它设置
tok为正则表达式匹配的结果。
calc-next-token uses a cond construct to see if there is a number,
operator, or command letter at point by using the regular expressions
calc-number-regexp, calc-operator-regexp, and calc-command-regexp. According to which
regular expression was matched, it sets the variable calc-proc-fun to the name (symbol) of the
function that should be run (either calc-push-number, calc-operate, or calc-command), and it sets
tok to the result of the regular expression match.
在calc-eval中,我们看到了函数作为列表的思想的来源。funcall函数反映了 Lisp 中代码和数据之间几乎没有区别的事实。我们可以将一个由符号和一堆表达式组成的列表放在一起,并将其作为函数进行计算,使用符号作为函数名,表达式作为参数;这就是funcall的作用。在这种情况下,如下:
In calc-eval, we see where the idea of a function as a list comes in. The funcall function reflects the fact that there is little difference between code and data in Lisp. We can put together a list consisting of a symbol and a bunch of expressions and evaluate it as a function, using the symbol as the function name and the expressions as arguments; this is what funcall does. In this case, the following:
(funcall calc-proc-fun tok)
(funcall calc-proc-fun tok)
将calc-proc-fun的符号值视为要调用的函数的名称,并使用参数 来调用它tok。然后该函数执行以下三件事之一:
treats the symbol value of calc-proc-fun as the name of the function to
be called and calls it with the argument tok. Then
the function does one of three things:
如果标记是数字,则calc-push-number将数字压入堆栈。
If the token is a number, calc-push-number pushes the number onto the stack.
如果标记是运算符,则calc-operate对堆栈顶部的两个数字执行运算(见下文)。
If the token is an operator, calc-operate performs the operation on the top two numbers on the stack (see below).
如果令牌是命令,则calc-command执行适当的命令。
If the token is a command, calc-command performs the appropriate command.
函数calc-operate将函数作为数据列表的概念更进一步,将用户的标记直接转换为函数(算术运算符)。此步骤由函数read完成,该函数接受字符串并将其转换为符号。因此,calc-operate结合使用funcall和read ,如下所示:
The function calc-operate takes the idea of functions as lists of data a step further by converting the token from the user directly into a function (an arithmetic operator). This step is accomplished by the function read, which takes a character string and converts it into a symbol. Thus, calc-operate uses funcall and read in combination as follows:
(defun 计算操作(tok)
(让 ((op1 (calc-pop))
(op2 (计算-流行)))
(calc-push(funcall(读tok)op2 op1))))(defun calc-operate (tok)
(let ((op1 (calc-pop))
(op2 (calc-pop)))
(calc-push (funcall (read tok) op2 op1))))该函数采用算术运算符的名称(作为字符串)作为其参数。正如我们之前看到的,字符串tok
是从缓冲区中提取的标记*Calc*,在本例中是算术运算符,例如+or
*。 calc -operate函数使用pop函数将顶部的两个参数从堆栈中弹出,这与之前的使用类似
cdr。read
将标记转换为符号,从而转换为算术函数的名称。因此,如果运算符是+,则funcall会被调用,如下所示:
This function takes the name of an arithmetic operator (as a string)
as its argument. As we saw earlier, the string tok
is a token extracted from the *Calc* buffer, in
this case, an arithmetic operator such as + or
*. The calc-operate function pops the top two
arguments off the stack by using the pop function, which is similar to the use of
cdr earlier. read
converts the token to a symbol, and thus to the name of an arithmetic
function. So, if the operator is +, then funcall is called as here:
(funcall '+ op2 op1)
(funcall '+ op2 op1)
因此,使用两个参数调用函数+ ,这与(+ op2 op1)完全相同。最后,函数的结果被推回堆栈。
Thus, the function + is called with the two arguments, which is exactly equivalent to simply (+ op2 op1). Finally, the result of the function is pushed back onto the stack.
所有这些巫术都是必要的,例如,用户可以键入加号,Lisp 会自动将其转换为加号函数。我们可以通过使用cond构造(如calc-next-token )编写calc-operate 来不太优雅且效率较低地完成同样的事情,如下所示:
All this voodoo is necessary so that, for example, the user can type a plus sign and Lisp automatically converts it into a plus function. We could have done the same thing less elegantly—and less efficiently—by writing calc-operate with a cond construct (as in calc-next-token), which would look like this:
(defun 计算操作(tok)
(让 ((op1 (calc-pop))
(op2 (计算-流行)))
(cond ((等于 tok "+")
(+ op2 op1))
((等于“-”)
(- op2 op1))
((等于“*”)
(* op2 op1))
((等于“/”)
(/op2op1))
(t
(% op2 op1)))))(defun calc-operate (tok)
(let ((op1 (calc-pop))
(op2 (calc-pop)))
(cond ((equal tok "+")
(+ op2 op1))
((equal tok "-")
(- op2 op1))
((equal tok "*")
(* op2 op1))
((equal tok "/")
(/ op2 op1))
(t
(% op2 op1)))))计算器模式代码中最后要注意的是函数
calc-mode,它启动该模式。它创建(并弹出)缓冲区*Calc*。然后它杀死缓冲区中所有现有的局部变量,将堆栈初始化为nil(空),并创建局部变量calc-proc-fun(请参阅前面的讨论)。最后,它将计算器模式设置为主要模式,设置模式名称,并激活本地键盘映射。
The final thing to notice in the calculator mode code is the function
calc-mode, which starts the mode. It
creates (and pops to) the *Calc* buffer. Then it
kills all existing local variables in the buffer, initializes the
stack to nil (empty), and creates the local
variable calc-proc-fun (see the
earlier discussion). Finally it sets Calculator mode as the major
mode, sets the mode name, and activates the local keymap.
现在你应该能够 了解计算器模式的所有代码。您会发现实际上根本没有那么多代码!这证明了 Lisp 的强大以及内置 Emacs 函数的多功能性。一旦您了解了此模式的工作原理,您就应该准备好开始自己的模式了。废话不多说,代码如下:
Now you should be able to understand all of the code for the calculator mode. You will notice that there really isn't that much code at all! This is testimony to the power of Lisp and the versatility of built-in Emacs functions. Once you understand how this mode works, you should be ready to start rolling your own. Without any further ado, here is the code:
;;计算器模式。
;;
;;支持运算符 +、-、*、/ 和 %(余数)。
;;命令:
;; c 清空堆栈
;; = 打印栈顶的值
;; p 打印整个堆栈内容
;;
(defvar 计算模式映射 nil
“计算器模式缓冲区的本地键盘映射。”)
;设置计算器模式键盘映射
; Cj(换行)作为“eval”键
(如果计算模式地图
零
(setq calc-mode-map (make-sparse-keymap))
(定义键计算模式映射“\Cj”'计算评估))
(defconst 计算数正则表达式
“-?\\([0-9]+\\.?\\|\\.\\)[0-9]*\\(e[0-9]+\\)?”
“用于识别数字的正则表达式。”)
(defconst calc-operator-regexp "[-+*/%]"
“用于识别运算符的正则表达式。”)
(defconst calc-command-regexp "[c=ps]"
“用于识别命令的正则表达式。”)
(defconst calc-whitespace "[ \t]"
“用于识别空格的正则表达式。”)
;;堆栈函数
(defun calc-push(num)
(如果(数字 p 数字)
(setq calc-stack (cons num calc-stack))))
(defun calc-top ( )
(如果(不是计算堆栈)
(错误“堆栈为空。”)
(汽车计算堆栈)))
(defun calc-pop ( )
(让((val(计算顶部)))
(如果值
(setq 计算堆栈 (cdr 计算堆栈)))
值))
;;用户命令的功能:
(defun calc-print-stack ()
“从上到下打印堆栈的全部内容。”
(如果计算堆栈
(程序
(插入“\n”)
(让((stk计算堆栈))
(而计算堆栈
(插入(数字到字符串(calc-pop))“”))
(setq calc-stack stk)))
(错误“堆栈为空。”)))
(defun calc-clear-stack ( )
“清空堆栈。”
(setq calc-stack nil)
(消息“堆栈已清除。”))
(defun calc-命令 (tok)
“给定命令令牌,执行适当的操作。”
(cond ((等于 tok "c")
(计算-清除-堆栈))
((等于“=”)
(插入“\n”(数字到字符串(calc-top))))
((等于 tok "p")
(计算-打印-堆栈))
(t
(消息(concat“无效命令:”tok)))))
(defun 计算操作(tok)
“给定一个算术运算符(作为字符串),弹出两个数字
出栈,执行 tok 操作(以字符串形式给出),push
结果入栈。”
(让 ((op1 (calc-pop))
(op2 (计算-流行)))
(calc-push(funcall(读tok)op2 op1))))
(defun calc-push-number(tok)
“给定一个数字(作为字符串),将其压入(作为数字)
到堆栈上。”
(calc-push (字符串到数字 tok)))
(defun calc-无效-tok (tok)
(错误(连接“无效令牌:” tok))
(defun calc-next-token ( )
“根据正则表达式搜索选取下一个标记。
作为副作用,将点提前一过令牌,
并设置用于处理令牌的函数名称。”
(让(托克)
(cond ((查看 calc-number-regexp)
(goto-char (匹配结束 0))
(setq calc-proc-fun 'calc-push-number))
((查看 calc-operator-regexp)
(前向字符 1)
(setq calc-proc-fun '计算操作))
((查看 calc-command-regexp)
(前向字符 1)
(setq calc-proc-fun 'calc-command))
((看着 ”。”)
(前向字符 1)
(setq calc-proc-fun 'calc-invalid-tok)))
;;拿起令牌并前进到它(以及过去的空白)
(setq tok (缓冲区子串 (匹配开始 0) (点)))
(如果(查看 calc-whitespace)
(goto-char (匹配结束 0)))
托克))
(defun 计算评估 ( )
“计算器模式的主要评估功能。
处理输入行上的所有标记。”
(交互的)
(行首)
(同时(不是(eolp))
(让((tok(计算下一个令牌)))
(funcall calc-proc-fun tok)))
(插入“\n”))
(defun 计算模式 ( )
“计算器模式,使用 HP 风格后缀表示法。
理解算术运算符 +、-、*、/ 和 %,
加上以下命令:
c 清除堆栈
= 打印栈顶
p 打印整个堆栈内容(从上到下)
换行 (Cj) 绑定到一个评估函数
将评估当前行上的所有内容。不
除了分隔数字之外,空格是必要的。”
(交互的)
(弹出到缓冲区“*Calc*”零)
(杀死所有本地变量)
(make-local-variable 'calc-stack)
(setq calc-stack nil)
(make-local-variable 'calc-proc-fun)
(setq 主模式 '计算模式)
(setq 模式名称“计算器”)
(使用本地地图计算模式地图));; Calculator mode.
;;
;; Supports the operators +, -, *, /, and % (remainder).
;; Commands:
;; c clear the stack
;; = print the value at the top of the stack
;; p print the entire stack contents
;;
(defvar calc-mode-map nil
"Local keymap for calculator mode buffers.")
; set up the calculator mode keymap with
; C-j (linefeed) as "eval" key
(if calc-mode-map
nil
(setq calc-mode-map (make-sparse-keymap))
(define-key calc-mode-map "\C-j" 'calc-eval))
(defconst calc-number-regexp
"-?\\([0-9]+\\.?\\|\\.\\)[0-9]*\\(e[0-9]+\\)?"
"Regular expression for recognizing numbers.")
(defconst calc-operator-regexp "[-+*/%]"
"Regular expression for recognizing operators.")
(defconst calc-command-regexp "[c=ps]"
"Regular expression for recognizing commands.")
(defconst calc-whitespace "[ \t]"
"Regular expression for recognizing whitespace.")
;; stack functions
(defun calc-push (num)
(if (numberp num)
(setq calc-stack (cons num calc-stack))))
(defun calc-top ( )
(if (not calc-stack)
(error "stack empty.")
(car calc-stack)))
(defun calc-pop ( )
(let ((val (calc-top)))
(if val
(setq calc-stack (cdr calc-stack)))
val))
;; functions for user commands:
(defun calc-print-stack ( )
"Print entire contents of stack, from top to bottom."
(if calc-stack
(progn
(insert "\n")
(let ((stk calc-stack))
(while calc-stack
(insert (number-to-string (calc-pop)) " "))
(setq calc-stack stk)))
(error "stack empty.")))
(defun calc-clear-stack ( )
"Clear the stack."
(setq calc-stack nil)
(message "stack cleared."))
(defun calc-command (tok)
"Given a command token, perform the appropriate action."
(cond ((equal tok "c")
(calc-clear-stack))
((equal tok "=")
(insert "\n" (number-to-string (calc-top))))
((equal tok "p")
(calc-print-stack))
(t
(message (concat "invalid command: " tok)))))
(defun calc-operate (tok)
"Given an arithmetic operator (as string), pop two numbers
off the stack, perform operation tok (given as string), push
the result onto the stack."
(let ((op1 (calc-pop))
(op2 (calc-pop)))
(calc-push (funcall (read tok) op2 op1))))
(defun calc-push-number (tok)
"Given a number (as string), push it (as number)
onto the stack."
(calc-push (string-to-number tok)))
(defun calc-invalid-tok (tok)
(error (concat "Invalid token: " tok))
(defun calc-next-token ( )
"Pick up the next token, based on regexp search.
As side effects, advance point one past the token,
and set name of function to use to process the token."
(let (tok)
(cond ((looking-at calc-number-regexp)
(goto-char (match-end 0))
(setq calc-proc-fun 'calc-push-number))
((looking-at calc-operator-regexp)
(forward-char 1)
(setq calc-proc-fun 'calc-operate))
((looking-at calc-command-regexp)
(forward-char 1)
(setq calc-proc-fun 'calc-command))
((looking-at ".")
(forward-char 1)
(setq calc-proc-fun 'calc-invalid-tok)))
;; pick up token and advance past it (and past whitespace)
(setq tok (buffer-substring (match-beginning 0) (point)))
(if (looking-at calc-whitespace)
(goto-char (match-end 0)))
tok))
(defun calc-eval ( )
"Main evaluation function for calculator mode.
Process all tokens on an input line."
(interactive)
(beginning-of-line)
(while (not (eolp))
(let ((tok (calc-next-token)))
(funcall calc-proc-fun tok)))
(insert "\n"))
(defun calc-mode ( )
"Calculator mode, using H-P style postfix notation.
Understands the arithmetic operators +, -, *, / and %,
plus the following commands:
c clear stack
= print top of stack
p print entire stack contents (top to bottom)
Linefeed (C-j) is bound to an evaluation function that
will evaluate everything on the current line. No
whitespace is necessary, except to separate numbers."
(interactive)
(pop-to-buffer "*Calc*" nil)
(kill-all-local-variables)
(make-local-variable 'calc-stack)
(setq calc-stack nil)
(make-local-variable 'calc-proc-fun)
(setq major-mode 'calc-mode)
(setq mode-name "Calculator")
(use-local-map calc-mode-map))以下是计算器模式的一些可能的扩展,作为练习提供。如果您尝试一下,您将增加对该模式代码和 Emacs Lisp 编程的总体理解。
The following are some possible extensions to the calculator mode, offered as exercises. If you try them, you will increase your understanding of the mode's code and Emacs Lisp programming in general.
^添加“power”运算符(4 5
^计算结果为1024)。 Emacs Lisp 中没有内置的 power 函数,但是您可以使用内置函数expt。
Add an operator ^ for
"power" (4 5
^ evaluates to 1024). There is no
built-in power function in Emacs Lisp, but you can use the built-in
function expt.
添加对八进制(以 8 为基数)和/或十六进制(以 16 为基数)数字的支持。八进制数以“0”开头,十六进制数以“0x”开头;因此,017 等于十进制 15,0x17 等于十进制 23。
Add support for octal (base 8) and/or hexadecimal (base 16) numbers. An octal number has a leading "0," and a hexadecimal has a leading "0x"; thus, 017 equals decimal 15, and 0x17 equals decimal 23.
添加运算符\+和将堆栈上的所有数字\*相加/相乘,而不仅仅是前两个数字(例如,计算结果为,
计算结果为)。[ 10 ]4 5 6 \+154 5 6 \*120
Add operators \+ and \* to
add/multiply all of the numbers on the stack,
not just the top two (e.g., 4 5 6 \+ evaluates
to 15, and 4 5 6 \*
evaluates to 120).[10]
作为对 Lisp 中列表处理知识的附加测试,请完成本章前面的示例(示例 5),该示例搜索compilation-error-regexp-alist以查找与编译器错误消息的匹配项。 (提示:复制列表,然后挑选顶部的重复元素,直到找到匹配项或列表耗尽。)
As an additional test of your knowledge of list handling in Lisp, complete the example (Example 5) from earlier in this chapter that searches compilation-error-regexp-alist for a match to a compiler error message. (Hint: make a copy of the list, then pick off the top element repeatedly until either a match is found or the list is exhausted.)
[ 8 ]不幸的是,因为这些变量是在成为模式本地变量之前定义的,所以仍然存在与全局变量名称冲突的问题。因此,使用尚未用于全局变量的名称仍然很重要。避免这种情况的一个好策略是使用以模式名称开头的变量名称。
[8] Unfortunately, because such variables are defined before they are made local to the mode, there is still a problem with name clashes with global variables. Therefore, it is still important to use names that aren't already used for global variables. A good strategy for avoiding this is to use variable names that start with the name of the mode.
现在你明白了
在对主要模式进行编程的一些内容中,您可能会决定要自定义现有的模式。幸运的是,在大多数情况下,您不必担心更改任何模式的现有 Lisp 代码来执行此操作;您甚至可能不必查看代码。所有 Emacs 主要模式都有“钩子”,让您可以向其中添加自己的代码。适当地,这些被称为
模式挂钩。 Emacs 中的每个内置主要模式都有一个名为-hook的模式挂钩,其中
是模式或调用它的函数的名称。例如,C 模式有c-mode-hook,shell 模式有shell-mode-hook等。mode-name
mode-name
Now that you understand
some
of what goes into programming a major mode, you may decide you want
to customize an existing one. Luckily, in most cases, you
don't have to worry about changing any
mode's existing Lisp code to do this; you may not
even have to look at the code. All Emacs major modes have
"hooks" for letting you add your
own code to them. Appropriately, these are called
mode-hooks. Every built-in major mode in Emacs
has a mode hook called mode-name
-hook, where
mode-name is the name of the mode or the
function that invokes it. For example, C mode has c-mode-hook, shell mode has shell-mode-hook, etc.
到底什么是钩子?它是一个变量,其值是调用模式时要运行的一些 Lisp 代码。当您调用模式时,您运行一个 Lisp 函数,该函数通常会执行许多操作(例如,为特殊命令设置键绑定、创建缓冲区和局部变量等);模式调用函数通常做的最后一件事是运行模式的钩子(如果存在)。因此,钩子的“定位”使您有机会覆盖模式代码可能已设置的任何内容。例如,您定义的任何键绑定都会覆盖模式的默认绑定。
What exactly is a hook? It is a variable whose value is some Lisp code to run when the mode is invoked. When you invoke a mode, you run a Lisp function that typically does many things (e.g., sets up key bindings for special commands, creates buffers and local variables, etc.); the last thing a mode-invoking function usually does is run the mode's hook if it exists. Thus, hooks are "positioned" to give you a chance to override anything the mode's code may have set up. For example, any key bindings you define override the mode's default bindings.
我们之前看到 Lisp 代码可以用作 Lisp 变量的值;当您创建钩子时,这种用法会派上用场。在我们准确地向您展示如何创建钩子之前,我们需要介绍另一个 Lisp 基元函数:lambda。lambda与defun非常相似,因为它用于定义函数;不同之处在于lambda 定义了没有名称的函数(或者用 Lisp 的说法,“匿名函数”)。lambda的格式为:
We saw earlier that Lisp code can be used as the value of a Lisp variable; this use comes in handy when you create hooks. Before we show you exactly how to create a hook, we need to introduce yet another Lisp primitive function: lambda. lambda is very much like defun in that it is used to define functions; the difference is that lambda defines functions that don't have names (or, in Lisp parlance, "anonymous functions"). The format of lambda is:
(拉姆达 (args)code)
(lambda (args)code)
其中args是函数的参数,code是函数的主体。要将 lambda 函数指定为变量的值,您需要“引用”它以防止对其求值(运行)。也就是说,您使用以下形式:
where args are arguments to the function
and code is the body of the function. To
assign a lambda function as the value of a variable, you need to
"quote" it to prevent it from being
evaluated (run). That is, you use the form:
(设置qvar-name'( 拉姆达 ( )code))
(setqvar-name'(lambda ( )code))
因此,要为模式挂钩创建代码,您可以使用以下形式:
Therefore, to create code for a mode hook, you could use the form:
(setq-mode-name钩子 '( 拉姆达 ( )code for mode hook))
(setqmode-name-hook '(lambda ( )code for mode hook))
然而,您想要自定义的模式很可能已经定义了钩子。如果您使用该
setq表单,您将覆盖任何已经存在的挂钩。为了避免这种情况,您可以使用该函数
add-hook:
However, it's quite possible that the mode you want
to customize already has hooks defined. If you use the
setq form, you override whatever hooks already
exist. To avoid this, you can use the function
add-hook instead:
(添加钩子-'mode-name钩子 '( 拉姆达 ( )code for mode hook))
(add-hook'mode-name-hook '(lambda ( )code for mode hook))
使用模式挂钩最常见的事情是更改模式的特殊命令的一个或多个键绑定。这是一个例子:在第 7 章中,我们看到图片模式是创建简单线条图的有用工具。图片模式下的几个命令设置默认绘图方向。将方向设置为“向下”的命令picture-movement-down绑定到Cc。 (抄送 后跟句号)。这不像Cc <(用于picture-movement-left )或Cc ^(用于picture-movement-up )那样便于记忆,所以假设您希望将Cc v作为picture-movement-down的绑定 。毫不奇怪,图片模式的键盘映射称为 picture-mode-map,因此设置此键绑定所需的代码如下:
The most common thing done with mode hooks is to change one or more of the key bindings for a mode's special commands. Here is an example: in Chapter 7 we saw that picture mode is a useful tool for creating simple line drawings. Several commands in picture mode set the default drawing direction. The command to set the direction to "down," picture-movement-down, is bound to C-c . (C-c followed by a period). This is not as mnemonic a binding as C-c < for picture-movement-left or C-c ^ for picture-movement-up, so let's say you want to make C-c v the binding for picture-movement-down instead. The keymap for picture mode is, not surprisingly, called picture-mode-map, so the code you need to set this key binding is this:
(define-key picture-mode-map "\C-cv" '图片向下移动)
(define-key picture-mode-map "\C-cv" 'picture-movement-down)
图片模式的挂钩称为edit-picture-hook(因为edit-picture是调用图片模式的命令)。因此,要将此代码放入图片模式的挂钩中,应将以下内容放入您的.emacs 文件中:
The hook for picture mode is called edit-picture-hook (because edit-picture is the command that invokes
picture mode). So, to put this code into the hook for picture mode,
the following should go into your .emacs file:
(add-hook '编辑图片钩子
'( 拉姆达 ( )
(define-key picture-mode-map "\C-cv" '图片向下移动)))(add-hook 'edit-picture-hook
'(lambda ( )
(define-key picture-mode-map "\C-cv" 'picture-movement-down)))该指令创建一个 以一键绑定命令作为其主体的lambda函数。然后,每当您进入图片模式时(从您下次调用 Emacs 开始),此绑定就会生效。
This instruction creates a lambda function with the one key binding command as its body. Then, whenever you enter picture mode (starting with the next time you invoke Emacs), this binding will be in effect.
作为一个稍微复杂一点的示例,假设您创建了很多 HTML 页面。您使用 HTML 模式(参见第 8 章),但您发现没有输入标准head和
title标签的 Emacs 命令,尽管帮助文本提醒您它们的重要性。您想要编写自己的函数来插入这些字符串,并且想要将它们绑定到 HTML 模式下的击键。
As a slightly more complex example, let's say you
create a lot of HTML pages. You use HTML mode (see Chapter 8), but you find that there are no Emacs
commands that enter standard head and
title tags, despite the fact that the help text
reminds you of their importance. You want to write your own functions
to insert these strings, and you want to bind them to keystrokes in
HTML mode.
为此,您首先需要编写插入标记字符串的函数。最简单的方法就是插入文本:
To do this, you first need to write the functions that insert the tag strings. The simplest approach would just be to insert the text:
(defun html-head ( ) (交互的) (插入“<head></head>”)) (defun html-标题( ) (交互的) (插入“<标题></标题>”))
(defun html-head ( ) (interactive) (insert "<head></head>")) (defun html-title( ) (interactive) (insert "<title></title>"))
请记住,调用(interactive)是必要的,以便 Emacs 可以将这些函数用作用户命令。
Remember that the calls to (interactive) are
necessary so that Emacs can use these functions as user commands.
下一步是 使用第 10 章中描述的技术编写代码,将这些函数绑定到 HTML 模式的键盘映射(称为html-mode-map )中的击键。假设您要将这些函数绑定到Cc Ch(标题)和Cc Ct(标题)。Cc在许多 Emacs 模式中用作前缀键,例如我们在上一章中看到的语言模式。再说一次,这没有问题:
The next step is to write code that binds these functions to keystrokes in HTML mode's keymap, which is called html-mode-map, using the techniques described in Chapter 10. Assume you want to bind these functions to C-c C-h (head) and C-c C-t (title). C-c is used as a prefix key in many Emacs modes, such as the language modes we saw in the last chapter. Again, this is no problem:
(定义键 html-mode-map"\Cc\Ch" 'html-head) (定义键 html-mode-map"\Cc\Ct" 'html-title))
(define-key html-mode-map"\C-c\C-h" 'html-head) (define-key html-mode-map"\C-c\C-t" 'html-title))
最后,您需要将 Lisp 的这些行转换为html-mode-hook的值 。这是执行此操作的代码:
Finally, you need to convert these lines of Lisp into a value for html-mode-hook. Here is the code to do this:
(添加钩子'html-模式钩子
'( 拉姆达 ( )
(定义键 html-mode-map"\Cc\Ch" 'html-head)
(定义键 html-mode-map"\Cc\Ct" 'html-title)))(add-hook 'html-mode-hook
'(lambda ( )
(define-key html-mode-map"\C-c\C-h" 'html-head)
(define-key html-mode-map"\C-c\C-t" 'html-title)))如果您将此代码与早期的函数定义一起放入.emacs 文件中,则只要使用 HTML 模式,您就可以获得所需的功能。
If you put this code in your .emacs file,
together with the earlier function definitions, you get the desired
functionality whenever you use HTML mode.
但是,如果您尝试使用这些函数,您会发现与 HTML 模式下的其他标签插入命令相比,它们有一些明显的缺点。一方面,虽然其他帮助器命令将光标保留在开始和结束标记之间,但我们的插入将光标保留在结束标记之后,这不仅不一致,而且没有多大帮助。此外,虽然您插入的其他标签可以根据您首选的大小写进行自定义,或者围绕文档中的现有内容进行包装,但我们简单的插入调用不具备此类功能。
If you try using these functions, though, you'll find they have some noticeable drawbacks compared to the other tag insertion commands in HTML mode. For one thing, while the other helper commands leave your cursor in between the opening and closing tags, our insertions leave the cursor after the closing tag, which is not only inconsistent, but it's much less helpful. Also, while the other tags you insert can be customized in terms of your preferred capitalization, or wrapped around existing content in the document, our simple-minded insert calls give us no such capabilities.
幸运的是,添加我们想要的智能并不难。事实证明,HTML 模式是在文件 sgml-mode.el中定义的(我们通过将帮助的方便的描述函数命令Ch f应用于模式定义函数 HTML 模式来了解这一点。有了这些知识,就很容易了重要的是使用本章前面的“示例宝库”中显示的find-library-file实用程序来提取并研究使其工作的 Lisp 代码,快速寻找一个并行示例表明标签支持是。使用骨架函数生成器实现。无需过多讨论,事实证明我们要使用的代码是这样的:
Luckily, it's not hard to add the smarts we want. It turns out that HTML mode is defined in the file sgml-mode.el (we learned this by applying help's handy describe-function command, C-h f, to the mode-defining function HTML mode. Armed with this knowledge, it was an easy matter to pull up and study the Lisp code that makes it work using the find-library-file utility shown in "A Treasure Trove of Examples" earlier in this chapter. A little quick hunting to find a parallel example revealed that the tag support is implemented using a skeletal function generator. Without going into too much detail, it turns out that the code we want to use is this:
(定义骨架 html-head “HTML 文档标题部分。” 零 “<头>”_“</头>”) (定义骨架 html 标题 “HTML 文档标题。” 零 “<标题>”_“</标题>”)
(define-skeleton html-head "HTML document header section." nil "<head>" _ "</head>") (define-skeleton html-title "HTML document title." nil "<title>" _ "</title>")
Define-骨架函数设置要插入的骨架 HTML 代码,它通过根据传递给它的模板编写 Lisp 函数来完成此操作。它的第一个参数是要定义的 Lisp 函数的名称,下一个参数是该函数的文档字符串,解释它插入的内容。之后是一个可选提示,可用于自定义要插入的内容。我们不需要任何自定义,因此我们将其保留为
nil跳过提示。最后是要插入的字符串列表,我们用“ _”标记希望光标结束的位置。 (要了解有关此骨架系统工作方式的更多信息,请在insert-sculpture上调用describe-function。)
The define-skeleton function sets up the skeletal HTML code to be
inserted, and it does this by writing a Lisp function based on the
template you pass it. Its first argument is the name of the Lisp
function to define, and the next is a documentation string for that
function explaining what it inserts. After that comes an optional
prompt that can be used to customize the content to be inserted. We
don't need any customization, so we leave it as
nil to skip the prompt. Finally comes the list of
strings to be inserted, and we mark where we want the cursor to end
up with "_". (To
learn more about the way this skeleton system works, invoke describe-function on insert-skeleton.)
通过这些更改,我们的新命令就像 HTML 模式下的其他插入工具一样工作。甚至比这个例子中的具体 Lisp 代码更值得学习的是,我们用来创建它的技术。如果您能够培养从内置库中找到接近您想要的示例的技能和习惯,并深入研究它的工作原理以提出解决您问题的变体,那么您将祝你成为友好的 Emacs Lisp 大师,当你的朋友需要一个很酷的新技巧时,他们可以依赖他们。
With these changes, our new commands work just like the other insertion tools in HTML mode. Even more than the specific Lisp code that came out of this example, the technique we used to create it is worth learning. If you can develop the skills and habits involved in tracking down an example from the built-in libraries that is close to what you want, and digging into how it works just enough to come up with a variant that solves your problem, you'll be well on your way to becoming the friendly Emacs Lisp guru your friends rely on when they need a cool new trick.
这是第三个例子。假设您使用 C 进行编程,并且需要一个 Lisp 函数来计算文件中 C 函数定义的数量。下面的函数就可以解决这个问题;它有点类似于本章前面的count-lines-buffer示例。该函数通过在行的开头搜索来遍历当前缓冲区,查找(并计数)C 函数定义
{(诚然,这种简单化的方法假定了特定且严格的 C 编码风格):
Here is a third example. Let's say you program in C,
and you want a Lisp function that counts the number of C function
definitions in a file. The following function does the trick; it is
somewhat similar to the count-lines-buffer example earlier in the
chapter. The function goes through the current buffer looking for
(and counting) C function definitions by searching for
{ at the beginning of a line (admittedly, this
simplistic approach assumes a particular and rigid C coding style):
(defun 计数函数缓冲区 ( )
“计算缓冲区中 C 函数定义的数量。”
(交互的)
(保存游览
(goto-char (点-分钟))
(让((数0))
(同时(重新搜索“^{”nil t)
(setq 计数(1+ 计数)))
(消息“%d 个函数已定义。”计数))))(defun count-functions-buffer ( )
"Count the number of C function definitions in the buffer."
(interactive)
(save-excursion
(goto-char (point-min))
(let ((count 0))
(while (re-search-forward "^{" nil t)
(setq count (1+ count)))
(message "%d functions defined." count))))该函数中的重新搜索前向调用有两个额外的参数;其中第三个(最后一个)意味着“如果没有找到,则返回nil,不要发出错误信号。”第二个参数必须设置为nil默认值,以便可以提供第三个参数。[ 11 ]
The re-search-forward call in this
function has two extra arguments; the third (last) of these means
"if not found, just return nil,
don't signal an error." The second
argument must be set to nil, its default, so that
the third argument can be supplied.[11]
现在假设我们想在 C 模式下将此函数绑定到Cc f 。以下是我们设置c-mode-hook值的方法 :
Now assume we want to bind this function to C-c f in C mode. Here is how we would set the value of c-mode-hook:
(添加钩子'c-模式钩子
'( 拉姆达 ( )
(define-key c-mode-map "\C-cf" 'count-functions-buffer)))(add-hook 'c-mode-hook
'(lambda ( )
(define-key c-mode-map "\C-cf" 'count-functions-buffer)))将此代码和前面给出的函数定义放入您的
.emacs文件中,您将可以在 C 模式下使用此功能。
Put this code and the function definition given earlier in your
.emacs file, and this functionality will be
available to you in C mode.
作为模式钩子的最后一个例子,我们将兑现上一章的承诺。在讨论 C++ 模式时,我们注意到命令c-forward-into-nomenclature和c-backward-into-nomenclature被包含作为前向单词和
后向单词的替代命令,它们被
WordsLikeThis视为三个单词而不是一个单词,并且此功能对于 C++ 程序员很有用。问题是如何使通常调用前向词和后向词的按键调用新命令。
As a final example of mode hooks, we'll make good on
a promise from the previous chapter. When discussing C++ mode, we
noted that the commands c-forward-into-nomenclature and c-backward-into-nomenclature are included as
alternatives to forward-word and
backward-word that treat
WordsLikeThis as three words instead of one, and
that this feature is useful for C++ programmers. The question is how
to make the keystrokes that normally invoke forward-word and backward-word invoke the new commands instead.
首先,您可能认为答案只是为 C++ 模式创建一个钩子,将Mf和 Mb (前向字和后向字的默认绑定) 重新绑定到新命令,如下所示:
At first, you might think the answer is simply to create a hook for C++ mode that rebinds M-f and M-b, the default bindings for forward-word and backward-word, to the new commands, like this:
(添加钩子'c++-模式钩子
'( 拉姆达 ( )
(define-key c++-mode-map "\ef"
'c-前进到命名法中)
(define-key c++-mode-map "\eb"
'c-向后进入命名法)))(add-hook 'c++-mode-hook
'(lambda ( )
(define-key c++-mode-map "\ef"
'c-forward-into-nomenclature)
(define-key c++-mode-map "\eb"
'c-backward-into-nomenclature)))(请注意,我们使用c++-mode-map来进行键绑定,它是 C++ 模式的本地键盘映射。)但是,如果这些键已经被重新绑定,或者如果forward-word和 backward-word也绑定到其他键怎么办?击键序列(通常都是这样)?我们需要一种方法来找出哪些击键与这些函数绑定,以便我们可以将它们全部重置为新函数。
(Notice that we are using c++-mode-map, the local keymap for C++ mode, for our key bindings.) But what if those keys have already been rebound, or what if forward-word and backward-word are also bound to other keystroke sequences (which they usually are anyway)? We need a way to find out what keystrokes are bound to these functions, so that we can reset all of them to the new functions.
幸运的是,一个不起眼的函数为我们提供了这个信息,即where-is-internal。这个函数实现了where-is帮助命令的“本质” ,我们将在 第 14 章中看到它。where-is-internal返回绑定到作为参数给出的函数的击键原子列表。我们可以在while循环中使用这个列表来完成所有必要的重新绑定。这是代码:
Luckily, an obscure function gives us this information, where-is-internal. This function implements the "guts" of the where-is help command, which we will see in Chapter 14. where-is-internal returns a list of keystroke atoms that are bound to the function given as an argument. We can use this list in a while loop to do all of the rebinding necessary. Here is the code:
(添加钩子'c++-模式钩子
'( 拉姆达 ( )
(let ((fbinds (where-is-internal '前向字))
(bbinds (where-is-internal '向后字)))
(当 fbind
(define-key c++-mode-map (car fbinds)
'c-前进到命名法中)
(setq fbinds (cdr fbinds)))
(同时绑定
(define-key c++-mode-map (car bbinds)
'c-向后进入命名法)
(setq bbinds (cdr bbinds))))))(add-hook 'c++-mode-hook
'(lambda ( )
(let ((fbinds (where-is-internal 'forward-word))
(bbinds (where-is-internal 'backward-word)))
(while fbinds
(define-key c++-mode-map (car fbinds)
'c-forward-into-nomenclature)
(setq fbinds (cdr fbinds)))
(while bbinds
(define-key c++-mode-map (car bbinds)
'c-backward-into-nomenclature)
(setq bbinds (cdr bbinds))))))let语句顶部的两行分别将命令forward-word和backward-word 的所有键绑定获取到局部变量 fbinds和bbinds中。
The two lines in the top of the let statement get all of the key bindings of the commands forward-word and backward-word into the local variables fbinds and bbinds, respectively.
之后,有两个while
循环,其工作方式类似于
本章前面所示的计算器模式的打印堆栈函数。 while的这种使用是一种非常常见的 Lisp 编程结构:它通过获取第一个元素( car)、以某种方式使用它并将其从列表中删除 ( )来迭代列表的元素。当列表变空 ( )时循环结束,导致while测试失败。(setq
list
(cdr
list
)nil
After that, there are two while
loops that work like the print-stack
function of the calculator mode shown earlier in this chapter. This
use of while is a very common Lisp
programming construct: it iterates through the elements of a list by
taking the first element (the car),
using it in some way, and deleting it from the list
((setq
list
(cdr
list
)). The
loop finishes when the list becomes empty (nil),
causing the while test to fail.
在这种情况下,第一个while循环采用where-is-internal为forward-word找到的每个绑定,并在 C++ 模式的本地键盘映射 c++-mode-map中为新命令c-forward-into-创建绑定。命名法。第二个 while循环对back-word和c-backward-into-nomenclature执行相同的操作 。
In this case, the first while loop takes each of the bindings that where-is-internal found for forward-word and creates a binding in C++ mode's local keymap, c++-mode-map, for the new command c-forward-into-nomenclature. The second while loop does the same for backward-word and c-backward-into-nomenclature.
周围的代码将这些循环安装为 C++ 模式的挂钩,以便仅在调用 C++ 模式时才会发生重新绑定,并且仅在处于该模式的缓冲区中才处于活动状态。
The surrounding code installs these loops as a hook to C++ mode, so that the rebinding takes place only when C++ mode is invoked and is active only in buffers that are in that mode.
关于钩子的最后一句话:您可能已经注意到,我们在前面的章节中展示的一些模式自定义包含钩子,而其他则不包含。例如,前一章中用于设置首选 C 或 C++ 缩进样式的代码包含一个钩子:
One final word about hooks: you may have noticed that some of the mode customizations we have shown in previous chapters include hooks and others do not. For example, the code in the previous chapter to set your preferred C or C++ indentation style included a hook:
(添加钩子'c-模式钩子
'( 拉姆达 ( )
(c-set-style“ stylename”)
(c-切换-自动状态)))(add-hook 'c-mode-hook
'(lambda ( )
(c-set-style "stylename")
(c-toggle-auto-state)))而为c-macro-expand命令设置替代 C 预处理器命令名称的代码则没有:
whereas the code that sets an alternative C preprocessor command name for the c-macro-expand command did not:
(setq c-宏预处理器“/usr/local/lib/cpp -C”)
(setq c-macro-preprocessor "/usr/local/lib/cpp -C")
为什么是这样?实际上,自定义任何模式的正确方法是通过它的钩子——例如,前面的示例实际上应该是:
Why is this? Actually, the correct way to customize any mode is through its hook—for example, the preceding example should really be:
(添加钩子'c-模式钩子
'( 拉姆达 ( )
(setq c-宏预处理器“/usr/local/lib/cpp -C”)))(add-hook 'c-mode-hook
'(lambda ( )
(setq c-macro-preprocessor "/usr/local/lib/cpp -C")))如果您只想设置变量的值,则可以不用钩子,但如果您想运行c-set-style或用于绑定击键的函数,则严格需要钩子。这种二分法的确切原因将我们带入 Lisp 语言设计的黑暗深处,但其本质如下。
If you merely want to set values of variables, you can get away without a hook, but a hook is strictly required if you want to run functions like c-set-style or those used to bind keystrokes. The precise reason for this dichotomy takes us into the murky depths of Lisp language design, but it's essentially as follows.
如果您不调用定义变量的模式,则模式本地变量(例如c-macro-preprocessor )将不存在。因此,如果您不编辑 C 或 C++ 代码,那么您运行的 Emacs 中不存在c-macro-preprocessor,因为您尚未加载 C 模式(见下文)。然而,如果您的.emacs 文件包含setq来设置此变量的值,那么无论您是否使用过 C 模式,您都会调用该变量的存在。 Emacs 可以处理这个问题:当它加载 C 模式时,它会注意到您已经设置了变量的值并且不会覆盖它。
Variables that are local to modes, like c-macro-preprocessor, do not exist if you don't invoke the mode in which they are defined. So, if you aren't editing C or C++ code, then c-macro-preprocessor doesn't exist in your running Emacs, because you haven't loaded C mode (see below). Yet if your .emacs file contains a setq to set this variable's value, then you call the variable into existence whether or not you ever use C mode. Emacs can deal with this: when it loads C mode, it notices that you have already set the variable's value and does not override it.
然而,对于函数来说,情况有所不同。如果您在.emacs文件中调用了像c-set-style这样的模式本地函数
,那么(在大多数情况下)Emacs 会抱怨并显示消息,因为它不知道该函数,因此无法假设有关它能做什么。因此,您必须将此函数附加到 C 模式的钩子上:当 Emacs 运行您的钩子时,它已经加载了该模式,因此知道该函数的作用。Error in init file
However, the situation is different for functions. If you put a call
to a mode-local function like c-set-style in your .emacs
file, then (in most cases) Emacs complains, with the
message Error in init file, because it does not
know about this function and thus cannot assume anything about what
it does. Therefore you must attach this function to a hook for C
mode: by the time Emacs runs your hook, it has already loaded the
mode and therefore knows what the function does.
这些钩子示例只是最简单地说明您可以在自定义 Emacs 主要模式方面走多远。最好的部分是,使用钩子,您可以进行大量的自定义,而无需触及实现模式的代码。作为交换,您应该记住,当您编写自己的模式时,要考虑放置挂钩的有用位置,以便其他人可以 利用它们。
These examples of hooks are only the briefest indication of how far you can go in customizing Emacs's major modes. The best part is that, with hooks, you can do an incredible amount of customization without touching the code that implements the modes. In exchange, you should remember, when you do write your own modes, to think about useful places to put hooks so others can take advantage of them.
[ 11 ] re-search-forward和其他搜索函数的第二个参数给搜索带来了限制:如果给定一个整数值,n则不搜索过去的字符位置n。默认值
nil表示不限制搜索范围。
[11] The second
argument to re-search-forward—and other search
functions—gives a bound to the search: if given an integer
value n don't search past
character position n. A value of
nil, the default, means don't
give the search a bound.
当你成为了 精通 Emacs Lisp 编程,您将需要一个可以从 Emacs 中随意调用的 Lisp 函数和包库。当然,您可以在.emacs文件中定义一些小函数,但如果您正在为更专门的目的编写更大的代码片段,您将不希望使您的.emacs 文件变得混乱,也不希望 Emacs 花费所有时间。每次启动时都会评估代码。答案是构建您自己的 Lisp 库,类似于 Emacs 附带的 Lisp 目录,并包含其所有内置 Lisp 代码。创建库后,您可以在给定时间加载所需的任何 Lisp 包,而不必担心其他包。
After you have become proficient at Emacs Lisp programming, you will want a library of Lisp functions and packages that you can call up from Emacs at will. Of course, you can define a few small functions in your .emacs file, but if you are writing bigger pieces of code for more specialized purposes, you will not want to clutter up your .emacs file—nor will you want Emacs to spend all that time evaluating the code each time you start it up. The answer is to build your own Lisp library, analogous to the Lisp directories that come with Emacs and contain all of its built-in Lisp code. After you have created a library, you can load whatever Lisp packages you need at a given time and not bother with the others.
创建库需要两个简单的步骤。首先,创建一个用于存放 Lisp 代码的目录。大多数人 在他们的主目录中创建一个elisp子目录。 Lisp 文件的名称应以.el结尾 (您的.emacs文件是一个例外)。第二步是让 Emacs 知道您的目录,以便当您尝试加载 Lisp 包时,Emacs 知道在哪里找到它。 Emacs 在全局变量load-path中跟踪此类目录,该变量是目录名称字符串列表。
Creating a library requires two simple steps. First, create a directory in which your Lisp code will reside. Most people create a elisp subdirectory of their home directory. Lisp files are expected to have names ending in .el (your .emacs file is an exception). The second step is to make your directory known to Emacs so that when you try to load a Lisp package, Emacs knows where to find it. Emacs keeps track of such directories in the global variable load-path, which is a list of strings that are directory names.
load-path的初始值由 Emacs 附带的 Lisp 目录的名称填充,例如/usr/local/emacs/lisp。您需要将您自己的 Lisp 目录的名称添加到load-path中。进行此添加的一种方法是使用 Lisp 函数append,它将任意数量的列表参数连接在一起。例如,如果您的 Lisp 目录是~<yourname>/lisp,您可以将以下内容放入.emacs文件中:
The initial value for load-path is populated with the names of the Lisp directories that come with Emacs, e.g., /usr/local/emacs/lisp. You will need to add the name of your own Lisp directory to load-path. One way to make this addition is to use the Lisp function append, which concatenates any number of list arguments together. For example, if your Lisp directory is ~<yourname>/lisp, you would put the following in your .emacs file:
(setq 加载路径(追加加载路径(列表“~ yourname/lisp”)))(setq load-path (append load-path (list "~yourname/lisp")))函数列表是必要的,因为附加的所有参数都必须是列表。这行代码必须位于.emacs文件中从 Lisp 目录加载包的任何命令之前。
The function list is necessary because all of the arguments to append must be lists. This line of code must precede any commands in your .emacs file that load packages from your Lisp directory.
当您加载库时,Emacs 按照目录在load-path中出现的顺序搜索目录;因此,在这种情况下,Emacs 首先搜索其默认的 Lisp 目录。如果您希望首先搜索您的目录,您应该使用前面描述的cons函数而不是append,如下所示:
When you load a library, Emacs searches directories in the order in which they appear in load-path; therefore, in this case, Emacs searches its default Lisp directory first. If you want your directory to be searched first, you should use the cons function described earlier instead of append, as follows:
(setq 加载路径 (cons "~ yourname/lisp" 加载路径))(setq load-path (cons "~yourname/lisp" load-path))如果您想用自己的标准 Emacs 软件包之一替换其中一个,则此形式非常有用。例如,如果您编写了自己的 C 模式版本并希望使用它而不是标准包,则可以使用此形式。请注意,此处的目录名称没有被list调用包围,因为cons的第一个参数可以是原子(在本例中为字符串)。这种情况类似于使用cons将值压入堆栈,如前面描述的计算器模式。
This form is useful if you want to replace one of the standard Emacs packages with one of your own. For example, you'd use this form if you've written your own version of C mode and want to use it instead of the standard package. Notice that the directory name here is not surrounded by a call to list because cons's first argument can be an atom (a string in this case). This situation is similar to the use of cons for pushing values onto stacks, as in the calculator mode described earlier.
如果您希望 Emacs 在任何给定时间搜索您恰好所在的目录,只需添加nil到load-path,可以通过
cons添加它,也可以通过
append添加它。采取这一步类似于 put 。在你的 Unix PATH 环境变量中。
If you want Emacs to search the directory you happen to be in at any
given time, simply add nil to load-path, either by prepending it via
cons or by appending it via
append. Taking this step is
analogous to putting . in your Unix PATH
environment variable.
创建私有 Lisp 库并告诉 Emacs 在哪里可以找到它之后,您就可以加载和使用您创建的 Lisp 包了。有多种方法可以将 Lisp 包加载到 Emacs 中。其中第一个应该在第 10 章中熟悉:
After you have created a private Lisp library and told Emacs where to find it, you're ready to load and use the Lisp packages that you've created. There are several ways of loading Lisp packages into Emacs. The first of these should be familiar from Chapter 10:
输入Mx load-library Enter作为用户命令;参见第 10 章。
Type M-x load-library Enter as a user command; see Chapter 10.
(load
将“ package-name”行放入)
Lisp 代码中。将这样的一行放入
.emacs
文件中,使 Emacs 在启动时加载该包。
Put the line (load
"package-name")
within Lisp code. Putting a line like this into your
.emacs
file makes Emacs
load the package whenever you start it.
使用命令行选项调用 Emacs 。此操作加载包。"-l
package-name
"package-name
Invoke Emacs with the command-line option "-l
package-name
". This
action loads the package package-name.
将行(autoload
' function
" filename"放入)
Lisp 代码中(通常在
.emacs
文件中),如第 10 章 所述。此操作会导致 Emacs 在您执行给定的
. [ 12 ]function
Put the line (autoload
'function
"filename")
within Lisp code (typically in your
.emacs
file), as described
in Chapter 10. This action causes Emacs to load
the package when you execute the given
function.[12]
创建后 在您的 Lisp 目录中,您可以通过对 Lisp 文件进行字节编译或将其代码转换为字节代码(一种更紧凑、机器可读的形式)来更有效地加载和运行 Lisp 文件 。对 Lisp 文件filename.el进行字节编译 会创建字节代码文件filename.elc。字节代码文件的大小通常是非字节编译文件大小的 40% 到 75%。
After you have created your Lisp directory, you can make loading and running your Lisp files more efficient by byte-compiling them, or translating their code into byte code, a more compact, machine-readable form. Byte-compiling the Lisp file filename.el creates the byte code file filename.elc. Byte code files are typically 40 to 75 percent of the size of their non-byte-compiled counterparts.
尽管字节编译文件效率更高,但它们并不是绝对必要的。 load -library
命令在给出参数时filename,首先查找名为
<filename>.elc的文件。如果不存在,它将尝试
<filename>.el,即非字节编译版本。如果不存在,它最终会尝试<filename>。因此,您可以对.emacs文件进行字节编译,如果.emacs
很大,这可能会导致启动速度更快
。
Although byte-compiled files are more efficient, they are not
strictly necessary. The load-library
command, when given the argument filename,
first looks for a file called
<filename>.elc. If that
doesn't exist, it tries
<filename>.el, that is, the
non-byte-compiled version. If that doesn't exist, it
finally tries just <filename>. Thus, you
can byte-compile your .emacs file, which may
result in faster startup if your
.emacs
is large.
您可以通过将光标放在函数中的任意位置并输入Mxcompile-defun 来对 Lisp 代码缓冲区中的单个函数进行字节编译。您可以通过调用Mx byte-compile-file Enter并提供文件名来对Lisp 的整个文件进行字节编译。如果省略.el后缀,Emacs 会附加它并要求确认。如果您更改了文件但尚未保存,Emacs 会建议先保存它。
You can byte-compile a single function in a buffer of Lisp code by placing your cursor anywhere in the function and typing M-x compile-defun. You can byte-compile an entire file of Lisp by invoking M-x byte-compile-file Enter and supplying the filename. If you omit the .el suffix, Emacs appends it and asks for confirmation. If you have changed the file but have not saved it, Emacs offers to save it first.
然后,当字节编译器开始工作时,您将在迷你缓冲区中看到一个有趣的小显示:正在编译的函数名称一闪而过。字节编译器创建一个与原始 Lisp 文件同名但附加了内容的文件c
;因此,<filename>.el变为
<filename>.elc,
.emacs变为.emacs.elc。
Then you will see an entertaining little display in the minibuffer as
the byte-compiler does its work: the names of functions being
compiled flash by. The byte-compiler creates a file with the same
name as the original Lisp file but with c
appended; thus, <filename>.el becomes
<filename>.elc, and
.emacs becomes .emacs.elc.
最后,如果您开发一个包含多个 Lisp 文件的目录,并且对其中一些文件进行了更改,则可以使用byte-recompile-directory命令仅重新编译那些自字节编译以来已更改的 Lisp 文件(类似于Unix make实用程序)。只需输入Mx byte-recompile-directory Enter并提供 Lisp 目录的名称,或者直接按Enter键获取默认目录(即当前目录)。
Finally, if you develop a directory with several Lisp files, and you make changes to some of them, you can use the byte-recompile-directory command to recompile only those Lisp files that have been changed since being byte-compiled (analogously to the Unix make utility). Just type M-x byte-recompile-directory Enter and supply the name of the Lisp directory or just press Enter for the default, which is the current directory.
如果您编写大型程序或长文档,您可能至少遇到过一次这样的情况:您所做的更改最终证明是一件坏事,结果却感到困惑和受阻,因为您不确定到底如何做扭转它们并回到已知良好状态。或者,也许您已经向其他人发布了程序或文档,然后收到了错误修复或评论,但您无法正确集成,因为您无法恢复该人正在使用的旧版本。也许您是开发或文档团队的成员,并且感到需要某种方式来保留更改历史记录,以表明谁负责每个更改。
If you write either large programs or long documents, you have probably been caught at least once in a situation where you've made changes that turned out to be a bad thing, only to be confused and stymied because you weren't sure exactly how to reverse them and get back to a known good state. Or, perhaps you've released a program or document to someone else, then gotten a bug fix or a comment that you couldn't integrate properly because you couldn't recover the old version that person was working with. Perhaps you're a member of a development or documentation team and have felt the need for some way to keep change histories, indicating who was responsible for each change.
这些常见问题可以通过 版本控制系统来解决。版本控制系统可以自动帮助您保存一个文件或一组文件的更改历史记录。它允许您恢复该历史记录中的任何阶段,并且可以轻松获取有关版本之间差异的报告。
These common kinds of problems can be addressed with a version control system. A version control system gives you automated help at keeping a change history for a file or group of files. It allows you to recover any stage in that history, and it makes getting reports on the differences between versions easy.
如今,运行 Emacs 的机器上广泛使用了各种版本控制系统。有些是商业性的,但有大量免费、开放和强大的选择,我们的讨论重点关注这些似乎是合适的。从历史上看,Emacs 很大程度上是在 Unix 环境中与 SCCS 和 RCS 系统一起发展的,其对版本控制的内置支持反映了它们的方法和术语。如今,迄今为止最流行的是 CVS(它建立在 RCS 之上,赋予它更多的灵活性和功能),并且有一个名为 Subversion 的新系统开始流行。初步支持使用 Emacs 21.3.5 附带的 Subversion;其文档建议您检查 Subversion 站点http://subversion.tigris.org/来获取更新。
Today a variety of version control systems are widely available on machines that run Emacs. Some are commercial, but there are a wealth of free, open, and powerful choices, and it seems appropriate for our discussion to focus on these. Historically, Emacs evolved largely in a Unix environment alongside the SCCS and RCS systems, and its built-in support for version control reflects their approach and terminology. Today the most popular by far is CVS (which builds on RCS, giving it more flexibility and power), and there is a new system called Subversion that is starting to catch on. Preliminary support for working with Subversion shipped with Emacs 21.3.5; its documentation suggests you check the Subversion site, http://subversion.tigris.org/, for updates.
鉴于当您需要版本控制时,您通常非常需要它(并且您有足够多的其他挑战占据您的头脑),因此当今大多数集成开发环境为这些工具提供自动化支持也就不足为奇了。如果任何其他 IDE 可以做到这一点,那么现在您肯定可以预测 Emacs 也会这样做!
Given that when you need version control, you generally need it very badly (and you have enough other challenges to occupy your mind), it's not surprising that most integrated development environments today offer automated support for these tools. And if any other IDE does it, by now you can certainly predict that Emacs does too!
在本章中,我们将向您介绍名为 VC 的 Emacs 工具,这是一种 Emacs Lisp 次要模式,使版本控制系统的使用变得非常容易。 VC 为您运行所有版本控制命令(以与编译器模式相同的方式使用 Emacs 的子进程设施)。 VC 对你隐藏了几乎所有的接口细节;相反,您可以使用单个命令触发最基本的版本控制操作,Emacs 可以正确推断下一步需要做什么。
In this chapter, we'll introduce you to the Emacs facility called VC, an Emacs Lisp minor mode that makes using version control systems very easy. VC runs all version control commands for you (using Emacs' subprocess facilities in the same way that compiler modes do). VC hides almost all the details of their interfaces from you; instead, you can trigger most basic version control operations with a single command, with Emacs correctly deducing what needs to be done next.
如上所述,VC 架构的设计考虑了 RCS 的行为。因此,当我们解释 VC 时,我们将解释 Emacs 所呈现的 RCS 术语和行为。如果需要,我们将指出 CVS 行为方式的关键差异。反过来,Subversion 被设计为 CVS 的更现代版本,并且在与 Emacs 的交互方面与 CVS 类似。
As noted above, the VC architecture was designed with the behavior of RCS in mind. So as we explain VC, we'll explain the RCS terminology and behavior as Emacs presents it. Where needed, we'll point out key differences in the way CVS behaves. Subversion, in turn, is being designed as a more modern version of CVS, and acts like CVS with respect to its interactions with Emacs.
版本控制下的每个文件都有一个更改历史记录,其中包含初始版本和一系列(有时是分支树)后续修订版本。
Each file under version control has a change history that consists of an initial version and a series (or sometimes a branching tree) of subsequent revisions.
要使文件受版本控制,您 必须 注册;也就是说,您必须告诉版本控制系统将您开始使用的文件内容视为初始版本,并开始维护它的更改历史记录。[ 1 ]
To make a file version-controlled, you must register it; that is, you must tell the version control system to treat the file contents you're starting with as an initial version and begin maintaining a change history for it.[1]
过去,要更改已注册的文件,您必须检出该文件。这样做会通知版本控制系统您正在修改它。在 SCCS 和 RCS 下,这将锁定文件,以便在您完成之前没有其他人可以查看它(但其他人仍然可以查看它)。这个限制是开发 CVS(并发版本系统)的主要动机之一,它不加锁。相反,它会尝试在提交时协调所有并发更改,如下所述。即便如此,一些开发人员更喜欢配置 CVS 以在操作系统级别锁定文件,直到他们有意识地决定要对其中一个文件进行更改为止;这在很大程度上模仿了 RCS 的体验,尽管是在自愿的基础上。
To change a registered file, in the old days you'd have to check out the file. Doing so notifies the version control system that you're modifying it. Under SCCS and RCS, this would lock the file so that no one else could check it out until you were done (anyone else could still look at it, though). This limitation was one of the major motivations for the development of CVS, the Concurrent Versions System, which doesn't make locks. Instead, it tries to reconcile any concurrent changes at the time that they are committed, as described below. Even so, some developers prefer to configure CVS to keep files locked at the OS level until they consciously decide they want to make changes to one of them; this largely mimics the RCS experience, albeit on a voluntary basis.
在使用锁定的 SCCS 或 RCS 等系统中,有时您可能会发现自己无法检出文件,因为其他人已经 它已经锁了。也许那个人检查过之后就走开了,所以锁已经失效了。您可能想窃取锁,也就是说,通过其他人所做的任何更改来夺取工作文件的控制权,并负责自己签入一组干净的更改。 (随意执行此操作是不好的做法!)同样,自从 CVS 使并发编辑成为实用选项以来,这通常不是一个问题 - 回想一下 CVS 中的“C”代表“并发”。
In a system like SCCS or RCS that uses locking, you may sometimes find that you can't check out a file because someone else has it locked already. Perhaps that person checked it out and wandered away, so that the lock is stale. You may want to steal the lock—that is, seize control of the work file with whatever changes the other person has made and take responsibility for checking in a clean set of changes yourself. (It's bad practice to do this casually!) Again, this hasn't generally been an issue since CVS made concurrent edits a practical option—recall that the "C" in CVS stands for "concurrent."
在进行更改时 当您检查您的 工作文件(您已签出的工作副本)并对其进行试验时,您可以随时决定恢复工作文件,即放弃您的更改并撤消签出操作。对要保留的文件进行更改后,您必须签入这些更改。这样做会将它们作为文件的新修订版本永久添加到已保存的更改历史记录中。在 RCS 和 SCCS 下,它还会取消对您的工作文件的锁定,以便其他人可以查看并编辑它。在 CVS 和 Subversion 下,文件从未被锁定;相反,版本控制系统会尝试将您的更改与自签出时间以来可能进行的任何其他更改进行协调,如果发现冲突,则会大声寻求帮助(手动干预)。因为您从未真正在并发系统中签出文件,所以将更改集成回此类存储库的标准术语是提交而不是签入。 CVS 界面还允许您将其称为“签入”,以适应习惯于旧系统的人们,Emacs 也这么称呼它。
While making changes to your work file (the working copy you've checked out) and experimenting with them, you may decide at any time to revert the work file—that is, to throw away your changes and undo the check-out operation. After you've made changes to your file that you want to keep, you must check in those changes. Doing so adds them permanently to the saved change history as a new revision of the file. Under RCS and SCCS, it also removes the lock on your work file, so that other people can check it out and edit it. Under CVS and Subversion, the file was never locked; instead, the version control system tries to reconcile your changes with any other changes that might have been made since check-out time and yells for help (manual intervention) if it finds conflicts. Because you never really checked the file out in a concurrent system, the standard term for integrating your changes back into such a repository is commit rather than check in. The CVS interface also allows you to call it checking in, to accommodate people who are used to older systems, and that's what Emacs calls it too.
注册、检出、恢复和检入操作是基本操作。但您可能还想做其他事情。您还可以检索任何已保存的修订,获取任何两个已保存版本或任何已保存版本与您的(可能已修改的)工作文件之间的差异报告,甚至完全删除您想要丢弃的已保存修订(尽管这种情况很少见)。
The register, check-out, revert, and check-in operations are the basic ones. But you may want to do other things as well. You can also retrieve any saved revision, get a difference report between any two saved versions or any saved version and your (possibly modified) work file, or even completely remove saved revisions that you want to throw away (though this is rare).
如果在签入操作期间报告冲突,Emacs 会通过启动 Ediff 会话(在本章末尾描述)来帮助您解决这些冲突。如果您决定不使用 Ediff,您将看到版本控制系统在文件中表示的冲突,您可以手动解决它们或使用您认为方便的任何其他工具。如果您后来决定确实需要 Ediff 的帮助,则可以在编辑冲突文件时使用Mx vc-resolve-conflicts Enter 。
If conflicts are reported during a check-in operation, Emacs offers to help you resolve them by launching an Ediff session (described at the end of this chapter). If you decide against Ediff, you will see the conflicts as represented within the file by the version control system and you can address them manually or use whatever other tools you find convenient. If you later decide you do want help from Ediff after all, you can use M-x vc-resolve-conflicts Enter while you're editing the conflicted file.
大多数版本控制系统(以及我们在这里讨论的所有版本控制系统)将更改注释 与 每次修订。因此,每次签入注册文件时,您都可以将更改的说明添加到更改历史记录中,该说明不会成为文件本身的一部分。每次修订 有一个修订号,它标识了它在历史中的位置。 SCCS、RCS 和 CVS 的基本修订版是 1.1。如果历史记录是变化的线性序列(这对于小型项目来说是典型的),则序列号是由点分隔的两个数字字段。 Subversion 使用您无疑熟悉的更简单的修订版编号方案:第一个修订版编号为 1 ,后面的修订版编号为 2 。 。 。微妙,嗯?
Most version control systems (and all the ones we're talking about here) associate change comments with each revision. So each time you check in a registered file, you can add an explanation of the change to the change history, which won't be part of the file itself. Each revision has a revision number, which identifies its place in the history. The base revision in SCCS, RCS, and CVS is 1.1. If the history is a linear sequence of changes (which is typical for small projects), sequence numbers are two numeric fields separated by a dot. Subversion uses a simpler revision numbering scheme with which you're undoubtedly familiar: The first revision is numbered 1, the one that comes after it is 2 . . . subtle, eh?
可以启动分支,以便可以并行维护文件的变体版本。在这种情况下,主干仍然有两个字段修订号,但分支有更多字段。 SCCS 和 RCS 或 CVS 之间分支的确切命名约定很晦涩且不同;如果您需要详细了解它们,请查阅版本控制系统的文档。再一次,这在 Subversion 中要简单得多,它将整个源树作为一个单元进行版本化,并支持树的各个部分的高效副本。在 Subversion 中,分支只是另一个目录。关于版本控制系统,需要了解的内容比我们在这里介绍的要多得多,关于该主题的两本优秀的 O'Reilly 书籍是: Jennifer Vesperman 编写的Essential CVS和Ben Collins-Sussman、Brian W. Fitzpatrick 编写的 Version Control with Subversion,和 C. 迈克尔·皮拉托。
It is possible to start branches so that variant versions of files can be maintained in parallel. In such cases, the main trunk still has two-field revision numbers, but branches have more fields. The exact naming conventions for branches are arcane and different between SCCS and RCS or CVS; if you need to know about them in detail, consult the documentation for your version control system. Once again, this is a whole lot simpler in Subversion, which versions the entire source tree as a unit and supports efficient copies of parts of the tree. In Subversion, a branch is just another directory. There is a lot more to know about version control systems than we go into here, and two excellent O'Reilly books on the topic are: Essential CVS by Jennifer Vesperman and Version Control with Subversion by Ben Collins-Sussman, Brian W. Fitzpatrick, and C. Michael Pilato.
从历史上看,您必须了解三到四个不同的 shell 命令才能执行版本控制的基本操作(注册、签入、签出和恢复),并且您必须在编辑器外部(或在编辑器子 shell 中)执行每一个命令。这个过程既复杂又烦人,或者最多会分散您对代码和更改的工作流程的注意力。
Historically, you had to know three or four different shell commands to do the basic operations of version control (registration, check in, check out, and revert), and you had to do each one outside your editor (or in an editor subshell). This procedure was complicated and annoying, or at best a distraction from the flow of working on your code and changes.
VC的界面要简单得多。简单性来自于注意到无论版本控制文件处于什么状态,接下来通常只需要执行一件合乎逻辑的事情。规则如下:
VC's interface is much simpler. The simplicity comes from noticing that whatever state your version-controlled file is in, there is normally just one logical thing to do next. Here are the rules:
如果您的文件不受版本控制,那么下一个合乎逻辑的事情就是注册它并(如果相关)为您查看可修改的副本。
If your file isn't under version control, the next logical thing to do is register it and (where relevant) check out a modifiable copy for you.
如果它已注册,但没有被任何人签出,那么您通常要做的下一件事就是签出它,以便您可以编辑它(同样,在相关的情况下,例如如果您在“保持文件只读”中使用 CVS除非我说我想编辑它们”模式)。
If it's registered, but not checked out by anyone, the next thing you generally want to do is check it out so you can edit it (again, where relevant, such as if you're using CVS in a "keep files read-only unless I say I want to edit them" mode).
如果您对文件进行了更改,下一个合乎逻辑的事情就是将其重新签入,这可能涉及将您的更改与其他人所做的更改进行协调。
If you have made changes to the file, the next logical thing is to check it back in, which may involve reconciling your changes with those made by someone else.
更罕见的是,如果您使用的是 CVS 之前的系统之一,如果其他人签出了文件,您可能想要窃取锁(通知锁所有者您已经这样做了)。
Much more rarely, if you're using one of the pre-CVS systems, if someone else has a file checked out, you may want to steal the lock (notifying the lock owner that you've done so).
事实上,VC模式刚刚 一个基本命令:Cx vv(对于vc-next-action),您可以将其视为“对此文件执行下一个逻辑操作”,或者更准确地说:“将当前访问的文件带到下一个正常版本控制状态。 ”它遵循图 12-1中的箭头,该图描述了传统的版本控制周期。[ 2 ]该命令在 19 以后的所有 Emacs 中都可用;当您调用它时,它会自动获取 VC 的其余部分并完成其工作。
Indeed, VC mode has just one basic command: C-x v v (for vc-next-action), which you can think of as "do the next logical thing to this file" or, more precisely: "take the currently visited file to the next normal version control state." It follows the arrows in Figure 12-1, which describes the traditional version control cycle.[2] This command is available in every Emacs since 19; when you invoke it, it automatically fetches the rest of VC and does its job.
当然,还有更多的事情要做。一方面,当您签入文件的一组更改时,VC 会弹出一个缓冲区供您输入更改注释。同样,如果您处于较旧的版本控制环境中,当您窃取锁时,VC 会弹出一个缓冲区,请求解释。此说明将邮寄给锁所有者。
There's a little more to it than that, of course. For one thing, when you check in a set of changes to a file, VC pops up a buffer for you to enter a change comment. Similarly, if you're in an older version control environment, when you steal a lock, VC pops up a buffer requesting an explanation. This explanation is mailed to the lock owner.
VC 还为您提供恢复操作:Cx v u(对于vc-revert-buffer)。实际上,实现vc-next-action的函数会检查缓冲区自检出时间以来是否未被修改;如果是这样,它会提供恢复缓冲区并解锁工作文件而不是签入空更改。
VC gives you a revert operation as well: C-x v u (for vc-revert-buffer). Actually, the function that implements vc-next-action checks to see if the buffer is unmodified since check-out time; if so, it offers to revert the buffer and unlocks the work file rather than checking in an empty change.
虽然这种传统流程值得理解,因为它就是 VC 的设计方式,但使用当今的并发版本控制系统略有不同。幸运的是,它甚至更简单一些。由于编辑文档不需要获取锁,因此缺少一个 VC 步骤(或者,如果您愿意,可以将其视为隐式步骤)。如图 12-2所示。
Although it's worth understanding this traditional flow because it's how VC is designed, working with today's concurrent version control systems is slightly different. Luckily, it's even a little simpler. Because there is no need to obtain a lock in order to edit a document, one of the VC steps is missing (or, if you prefer, you can think of it as implicit). This is illustrated in Figure 12-2.
从未修改状态到已修改状态(相对于存储库中的版本)的转换显示为虚线,因为此处不再执行 VC 操作。您只需开始编辑要使用的文件即可。每当您告诉 VC 您想要“下一步操作”时,它就能够判断文档是否被修改。如果是,则当前版本已提交(“签入”,如果您愿意的话),并且系统会提示您输入更改注释。如果文件已注册但未修改,VC 只是在迷你缓冲区中显示一条消息,告诉您缓冲区是最新的。
The transition from the unmodified state to the modified state (with respect to the version in the repository) is shown as a dotted line, because you no longer perform a VC operation here. You just start editing the file you want to work with. Whenever you tell VC you want the "next action" it's able to tell whether the document is modified or not. If it is, the current version is committed ("checked in," if you will) and you're prompted for the change comments. If the file is registered but unmodified, VC simply displays a message in the minibuffer telling you that the buffer is up to date.
如果您希望将 CVS 配置为向您提供文件的只读版本,直到您明确选择编辑它们,您的工作流程仍将如图12-1所示。
If you prefer to configure CVS to give you read-only versions of files until you explicitly choose to edit them, your workflow will remain that of Figure 12-1.
[ 2 ]一些棘手的细节:您对新工作文件的第一个 vc-next-action通常会从“未注册”到“注册、解锁”,然后到“锁定、可编辑”。当一个命令可以涵盖典型情况时,为什么要让您为这两个步骤执行两个命令呢?如果您想注册文件但不签出它,请使用 Cx vi(对于vc-register)。随着 CVS 的出现,这一点在很大程度上变得毫无意义,如图12-2所示。
[2] Minor tricky detail: your very first vc-next-action on a new work file normally takes you from "unregistered" through "registered, unlocked," and then to "locked, editable." Why make you do two commands for those two steps when one will cover the typical case? If you want to register a file but not check it out, use C-x v i (for vc-register). With the advent of CVS, this point becomes largely moot as you'll see in Figure 12-2.
VC模式下,三个操作 通常会弹出一个缓冲区来接受评论或通知文本:签入、锁窃取和(在本章后面将解释的情况下)文件注册。在每种情况下,操作都会暂停,直到您键入 Cc Cc提交注释缓冲区。您可以立即输入评论并完成操作,也可以离开去做其他事情。 VC 会耐心等待,直到你准备好为止。如果删除弹出缓冲区,操作将被悄悄清除。
In VC mode, three operations typically pop up a buffer to accept comment or notification text: check in, lock stealing, and (under circumstances to be explained later in the chapter) file registration. In each case, the operation is on hold until you type C-c C-c to commit the comment buffer. You can enter a comment right away and finish the operation, or you can go off and do something else. VC waits patiently to commit until you are ready. If you delete the pop-up buffer, the operation is quietly scrubbed.
注释缓冲区是纯文本缓冲区。但是,每次提交注释缓冲区时,内容都会保存到注释缓冲区环中的新槽中。您可以使用Mp在环中向后循环 并使用Mn向前循环,也可以使用Mr在环中向后搜索文本并使用Ms向前 搜索文本。根据设计,这些键与您可以用来导航 Emacs 迷你缓冲区命令历史记录的键相同。到目前为止,这些命令中最常用的是Mp。能够回忆和编辑最后的更改注释通常很有用,因为进行一系列相关的更改是很常见的。
The comment buffer is a plain-text buffer. However, each time you commit a comment buffer, the contents are saved to a new slot in a ring of comment buffers. You can cycle backwards in the ring with M-p and forward with M-n, or you can search for text backwards in the ring with M-r and forward with M-s. By design, these are the same keys you can use to navigate an Emacs minibuffer command history. By far the most commonly used of these commands is M-p. Being able to recall and edit the last change comment is often useful since it's common to make a series of related changes.
为了让您了解 VC 可以做的其他事情,表 12-1提供了 VC 命令的摘要。每个人都会详细解释,但您可能可以从以下内容猜出他们的一些行为 命令名称。
To give you the flavor of the other things VC can do for you, Table 12-1 provides a summary of VC commands. Each one will be explained in detail, but you can probably guess some of their actions from the command names.
表 12-1。 VC命令
Table 12-1. VC commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CXVV C-x v v |
vc 下一个操作 vc-next-action |
转到下一个逻辑版本控制状态。 Go to the next logical version control state. |
|
CXVD C-x v d |
vc目录 vc-directory |
显示目录下的所有已注册文件。 Show all registered files beneath a directory. |
|
Cx v = C-x v = |
vc-差异 vc-diff |
生成版本差异报告。 Generate a version difference report. |
|
CX 视觉 C-x v u |
vc 恢复缓冲区 vc-revert-buffer |
丢弃自上次签入修订版以来的更改。 Throw away changes since the last checked-in revision. |
|
CX v ~ C-x v ~ |
vc 版本其他窗口 vc-version-other-window |
在另一个窗口中检索给定的修订版本。 Retrieve a given revision in another window. |
|
CXVl C-x v l |
vc打印日志 vc-print-log |
显示文件的更改注释和历史记录。 Display a file's change comments and history. |
|
CX六 C-x v i |
vc-寄存器 vc-register |
注册文件以进行版本控制。 Register a file for version control. |
|
CXVH C-x v h |
vc 插入标头 vc-insert-headers |
在文件中插入版本控制标头。 Insert version control headers in a file. |
|
CXVR C-x v r |
vc-检索快照 vc-retrieve-snapshot |
查看指定的项目快照。 Check out a named project snapshot. |
|
CX 与 C-x v s |
vc-创建快照 vc-create-snapshot |
创建命名项目快照。 Create a named project snapshot. |
|
CXVC C-x v c |
vc 取消版本 vc-cancel-version |
丢弃已保存的修订版本。 Throw away a saved revision. |
|
CXVA C-x v a |
vc 更新更改日志 vc-update-change-log |
更新 GNU 风格的 ChangeLog 文件。 Update a GNU-style ChangeLog file. |
这些命令在表中大致按照使用频率的递减顺序排列。这也是我们在以下各节中描述它们的顺序。所有 VC 命令都有公共前缀Cx v。您的手指会很快学会这个前缀,而您通常需要记住的只是单个命令后缀。两个小命令vc-rename-file和 vc-clear-context不绑定到键。稍后将对其进行解释。
These commands are ordered in the table roughly by decreasing frequency of use. This is also the order in which we'll describe them in the following sections. All VC commands have the common prefix C-x v. Your fingers will learn this prefix quickly, and all you usually have to remember is the single command suffix. Two minor commands, vc-rename-file and vc-clear-context, are not bound to keys. They are explained later on.
VC 抓取模式行的一部分每个缓冲区都会访问已注册的文件,并尝试使用它来让您了解该文件的版本控制状态。您会注意到,当缓冲区访问版本控制文件时,模式行的模式标记部分(显示在括号中)显示版本控制系统的名称和文件的修订号。
VC grabs a bit of the mode line for each buffer visiting a registered file and tries to use it to keep you informed of the version control state of that file. You'll notice that when a buffer is visiting a version-controlled file, the mode tags part of the mode line (shown in parentheses) shows the name of your version control system and a revision number for the file.
当这两个部分由破折号分隔时,该文件尚未检出;当它们用冒号分隔时,文件已被签出,修订号是您签出文件时的版本号。请注意,由于现在大多数人使用并发版本控制系统,您不会签出文件或获取锁定,因此您可以将破折号视为未修改的含义,而冒号表示已发生尚未提交的更改存储库。
When those two parts are separated by a dash, the file is not yet checked out; when they're separated by a colon, the file has been checked out, and the revision number is the one the file had when you checked it out. Note that since most people use concurrent version control systems these days, in which you don't check files out or obtain locks, you can think of the dash as meaning unmodified, while the colon means there have been changes that are not yet committed to the repository.
如果您没有看到这些指示符,则该文件尚未注册。这三种状态如图 12-3所示。
If you don't see these indicators, the file isn't registered yet. These three states are illustrated in Figure 12-3.
图 12-3。模式行显示不受版本控制的文件、相对于存储库未更改的文件以及已保存更改但尚未提交的文件。
Figure 12-3. Mode lines showing a file that is not under version control, one that is unchanged with respect to the repository, and one that has had changes saved but not yet committed.
我们之前说过VC使用许多版本控制系统中的任何一个(将来可能会添加更多)。它通过查找相应的主文件(即包含更改历史记录的文件)来选择对任何给定文件使用哪个文件。
We said earlier that VC uses any of a number of version control systems (more may be added in the future). It chooses which to use for any given file by looking for a corresponding master file—that is, a file containing a change history.
如果您使用 RCS,则每个项目目录通常都有一个 RCS master 所在的子目录。如果您使用 SCCS,则存在 SCCS子目录。 CVS 有点棘手;你的项目目录有一个包含控制信息的CVS子目录,但 CVS master 通常保存在一个中央存储库目录中,其位置通常由 CVSROOT 环境变量给出,并且可能完全位于另一台机器上,使用 pserver网络协议。 Subversion 也使用单独的服务器计算机来存储修订存储库;它通常使用基于 HTTP 的 WebDAV 进行事务处理。您的本地 Subversion 主文件保存在名为 .svn的子目录中。
If you're using RCS, each of your project directories usually has a subdirectory in which RCS masters live. If you're using SCCS, there are SCCS subdirectories. CVS is a little trickier; your project directory has a CVS subdirectory with control information in it, but CVS masters are typically kept in one central repository directory, the location of which is typically given by the CVSROOT environment variable, and will likely be on another machine completely, using the pserver network protocol. Subversion, too, uses a separate server machine to store the revision repository; it generally uses WebDAV over HTTP for its transactions. Your local Subversion master files are kept in a subdirectory named .svn.
如果 VC 在任何这些特殊目录中都找不到主目录,它会在与工作文件相同的目录中查找主目录(因此,如果您不介意工作目录,则不必创建 SCCS 或 RCS 目录)与大师混杂在一起)。 VC 检查每一种可能性(因此您实际上可以在同一目录中使用多个系统,尽管我们不建议这样做)。
If VC can't find a master in any of these special directories, it looks for a master in the same directory as your work file (so you don't have to create SCCS or RCS directories if you don't mind your work directories being cluttered with masters). VC checks each of these possibilities (so you can actually use more than one system in the same directory, although we don't recommend it).
如果 VC 在任何地方都找不到主目录,它会查找 RCS、SCCS、 CVS或.svn目录。尝试执行这些操作的顺序由变量vc-handled-backends控制 ,如本章后面的“自定义 VC”中所述。它找到的第一个告诉它要向哪个版本控制系统注册新文件。如果它找不到任何这些目录,并且您告诉它注册文件,它会假设您想要使用 RCS 并在工作文件旁边创建主文件。
If VC can't find a master anywhere, it looks for an RCS, SCCS, CVS, or .svn directory. The order in which these are attempted is controlled by the variable vc-handled-backends, described in "Customizing VC" later in this chapter. The first one it finds tells it which version control system to register new files with. If it can't find any of these directories, and you tell it to register a file, it assumes you want to use RCS and creates the master right alongside your work file.
要找出您的系统上可用的 SCCS、RCS、CVS 或 Subversion,只需分别执行命令COMB、RCS、
CVS和SVN,不带任何参数。如果您看到错误或使用消息,则相应的系统已准备好使用;如果你看到了command not found,那就不是了。
To find out which of SCCS, RCS, CVS, or Subversion is available on
your system, simply execute the commands comb, rcs,
cvs, and svn respectively, with no arguments. If you
see an error or usage message, the corresponding system is ready to
use; if you see command not found,
it's not.
我们已经解释了主命令 vc-next-action 的作用。现在我们将详细描述 VC 的其他每个命令。我们选择这些描述的顺序是为了让您从常用且简单的命令到罕见且更复杂的命令。
We've already explained what the main command, vc-next-action, does. Now we'll describe each of VC's other commands in detail. We have chosen the order of these descriptions to take you from frequently used and simpler commands to rarer and more complex ones.
因此,如果您认为自己已经学到了所有需要的内容,您可以阅读到本章的结尾或随时退出。但请尝试坚持下去,因为您可能会发现不太常见命令的描述为您提供了有关如何跟踪和组织项目文件的一些新想法。
You can, accordingly, read to the end of chapter or bail out at any point if you think you've learned all you need to. But try to persevere because you may find that the descriptions of the less common commands give you some new ideas about how to track and organize your project files.
通常,您的项目 想要将多个文件置于版本控制之下;它们包含特定目录和子目录下的所有文件是正常的。因此,查看当前工作目录下所有版本控制文件的列表通常很有用。能够对所有这些一起执行操作甚至更加有用。
Usually, the projects you want to put under version control have more than one file; it's normal for them to contain all the files under a specific directory and subdirectory. Therefore, seeing a list of all version-controlled files beneath the current working directory is often useful. Being able to perform an operation on all of them en masse is even more useful.
VC模式直接支持这一点。命令Cx vd(用于vc-directory)将您置于运行自定义 Dired(目录编辑)模式的缓冲区中,该模式列出当前目录下的所有已注册文件,指示哪些文件(如果有)已检出以及谁锁定了它们。此列表中的状态字段会通过签入和签出操作自动保持最新状态。
VC mode supports this directly. The command C-x v d (for vc-directory) puts you in a buffer running a customized Dired (directory editing) mode, which lists all registered files under the current directory, indicating which, if any, are checked out and who has locked them. The status field in this listing is automatically kept up to date by check-in and check-out operations.
如果您在此 Dired 缓冲区中标记多个文件(使用第 5 章中描述的普通 Dired 标记命令),然后执行vc-next-action 或vc-revert-buffer,VC 将对所有标记的文件执行该操作。执行此过程的最常见情况是当您想要同时签入对多个文件的更改时。 VC 可以帮助您:它会弹出一个仅包含一个更改注释的缓冲区,然后将其应用于签入创建的每个修订。
If you mark several files in this Dired buffer (with the ordinary Dired mark command described in Chapter 5) and then perform either a vc-next-action or vc-revert-buffer, VC performs that operation on all the marked files. The most common case in which you'll perform this procedure is when you want to check in changes to several files simultaneously. VC helps you out: it pops up a buffer for only one change comment, which it then applies to every revision the check-in creates.
vc -revert-buffer的设计比较保守一点;通常,它会针对每个文件提示您一次,以确保您确实要放弃其更改。
The vc-revert-buffer design is a bit more conservative; normally, it prompts you once for each file to make sure you really want to discard its changes.
一些 Dired 命令在 VC Dired 中反弹以运行版本控制命令。例如, =键击在当前文件上运行vc-diff而不是 Dired diff。 g 刷新目录中的所有 VC 状态字段。
Some Dired commands are rebound in VC Dired to run version-control commands. The = keystroke, for example, runs vc-diff on the current file rather than a Dired diff. And g refreshes all the VC status fields in the directory.
前面我们提到过 版本控制系统可以帮助您生成版本之间的差异报告。 VC 的命令是Cx v =(对于 vc-diff)。此命令通常会显示您的工作文件与您签入的上次修订版本之间的差异,以便您可以准确地看到再次签入时将提交哪些更改。
Earlier, we mentioned that version control systems help you generate difference reports between versions. VC's command for this is C-x v = (for vc-diff). This command normally shows you the difference between your work file and the last revision you checked in so that you can see exactly what changes you'll be committing if you check in again.
如果您为该命令提供前缀参数Cu Cx v =,它会提示您输入文件名和两个修订版号,并报告文件的这些修订版之间的差异。如果旧版本号为空(即,您只需在提示时按Enter键),则默认为最后签入的版本。如果较新的修订版为空,则默认为工作文件。因此,按Enter两次会将工作文件与上次签入存储库的文件进行比较,这是一项非常常见的任务。
If you give this command a prefix argument, C-u C-x v =, it prompts you for a file name and two revision numbers and reports the difference between those revisions of the file. If the older revision number is empty (that is, you simply press Enter at that prompt), it defaults to the last checked-in revision. If the newer revision is empty, it defaults to the work file. So pressing Enter twice compares the work file with what was last checked in to the repository, a very common task.
还可以获得整个项目文件树的差异报告。如果您为Cu Cx v =提供的文件名实际上是一个目录,您将看到该目录下每个注册文件的指定版本之间的差异。
It's also possible to get a difference report for a whole tree of project files. If the filename you give C-u C-x v = is actually a directory, you'll see the differences between your specified versions for every registered file underneath that directory.
按照设计,这样的差异报告可以使用 Larry Wall 的补丁实用程序(在所有现代 Unix 上可用)作为补丁进行传送和机械应用。当您通过电子邮件合作开发软件项目时,这是一个巨大的帮助;您可以下载源代码、注册它们、进行修改,然后使用一个命令生成完整的更改补丁集,并将其邮寄给您的协作者。
By design, such a difference report can be shipped and mechanically applied as a patch using Larry Wall's patch utility (available on all modern Unixes). This is a tremendous help when you're cooperating on a software project by email; you can download sources, register them, make modifications—and then, with one command, generate a complete patch set of your changes to mail to your collaborators.
这些报告的确切格式在版本控制系统之间有所不同,因为 VC 使用每个系统的本机差异报告器。[ 3 ]一般来说,输出类似于 Unix diff命令的输出。我们将在本章后面看到如何自定义报告。最后,本章的最后一节介绍了 Ediff,这是一种比较和解决多个文件或版本之间差异的替代且强大的方法。
The exact format of these reports varies somewhat between version control systems because VC uses each system's native difference reporter.[3] Generally, the output resembles that of the Unix diff command. We'll see how to customize the report later in this chapter. Finally, the last section of the chapter introduces Ediff, an alternate and powerful way to compare and resolve differences between multiple files or versions.
您可以使用 命令Cx v ~(对于vc-version-other-window)检索文件的任何已保存修订版本。修订版本将被检索到与您的文件同名的工作文件中,但标识其修订版本号的后缀除外(后缀实际上是一个点,后跟一个波浪号,后跟修订号,最后跟另一个波浪号)。这样你就可以检索多个修订,而且它们不会互相踩踏。当您想要查看文件的整个旧版本,而不是仅查看其与先前版本的更改或与后续版本的差异时,此命令非常有用。
You can use the command C-x v ~ (for vc-version-other-window) to retrieve any saved revision of a file. The revision is retrieved into a work file with the same name as your file, except for a suffix that identifies its revision number (the suffix is actually a dot, followed by a tilde, followed by the revision number, followed by another tilde). So you can retrieve several revisions, and they won't step on each other. This command is useful when you want to eyeball the entire old version of a file, as opposed to just its changes from previous versions or its differences from later ones.
如果您设置全局 Emacs Lisp 变量版本控制(VC 已使其几乎过时),则版本后缀格式与 Emacs 为保存的版本生成的格式非常接近。例如,如果您正在访问名为 的文件,并通过键入Cx v ~ 1foo.html检索版本 1.3 。 3 输入,您现在将访问一个名为 的文件
foo.html.~1.3~(因为它以波形符结尾,Dired 标记备份文件的命令将对其进行标记,如第 5 章所述)。
The version suffix format is very close to what Emacs generates for
saved versions if you set the global Emacs Lisp variable version-control (which VC has made pretty much
obsolete). For example, if you're visiting a file
named foo.html and you retrieve version
1.3 by typing C-x v ~ 1 . 3 Enter,
you will now be visiting a file named
foo.html.~1.3~ (and because it ends with a
tilde, Dired's command to flag backup files will
mark it, as discussed in Chapter 5).
如果您在 注册文件后,VC 会弹出一个缓冲区,其中包含该文件的更改历史记录。此命令对于查看与每个修订版相关的更改注释最有用。
If you use C-x v l (for vc-print-log) on a registered file, VC pops up a buffer containing that file's change history. This command is most useful for viewing the change comments associated with each revision.
通常,注册一个文件 使用非并发版本控制系统的Cx vv(对于vc-next-action )进行版本控制也会检查可编辑副本。有时,只注册文件而不检出它是很有用的。命令Cx v i(对于vc-register)可以执行此操作。随着现代并发版本控制系统的出现,这种区别正在消失。
Normally, registering a file for version control with C-x v v (for vc-next-action) with a nonconcurrent version control system also checks out an editable copy. Occasionally it's useful to be able to just register a file without checking it out. The command C-x v i (for vc-register) does this. With modern concurrent version control systems, this distinction is fading away.
大多数版本控制系统 鼓励您在文件中嵌入一个或多个神奇字符串,这些字符串会在签入、签出和恢复时自动更新。这些字符串的目的是自动携带有关文件当前修订号、上次修改者以及上次签入时间的信息。
Most version control systems encourage you to embed in your file one or more magic strings that get automatically updated at check-in, check-out, and revert time. The purpose of these strings is to carry automatically inserted information about the current revision number of the file, who last modified it, and when it was last checked in.
这些标头字符串在文件中很大程度上复制了 VC 放在模式行上的版本信息,以及您可以使用Cx vl获取的其余信息 (对于vc-print-log)。此功能可能看起来不太有用,但(特别是)嵌入版本字符串可以使从已编译的二进制程序中挖掘版本控制信息成为可能。
These header strings largely duplicate within the file the version information that VC puts on the mode line—and the rest of that information you can get with C-x v l (for vc-print-log). This feature might not seem very useful, but (in particular) embedding a version string can make it possible to mine version-control information out of a compiled binary program.
此外,您可能经常通过 Emacs 以外的其他方式查看版本控制文件。如果是这样,您将不会有显示版本控制信息的 Emacs 模式行,并且在文件中显示神奇的标头有一定的价值。因此,VC 为您提供了插入它们的命令。 (请注意,VC 插入的是标头的格式正确的占位符;每次提交文件时,底层版本控制系统都会填充实际值。)
Further, you may frequently view version-controlled files through something other than Emacs. If so, you won't have an Emacs mode line displaying version control information, and there is some value in having the magic headers visible in the file. Accordingly, VC provides you with a command to insert them. (Note that what VC inserts are correctly formatted placeholders for the headers; the actual values get filled in by the underlying version control system each time you commit the file.)
如果您在访问已注册且可编辑的文件时键入Cx vh(对于vc-insert-headers),VC 会尝试根据文件的语法确定如何插入版本控制标头作为注释,然后执行此操作。 VC 了解 C 和 Java 代码,尤其是nroff / troff / groff代码,并且通常可以从 Emacs 的comment-start和comment-end全局变量(由每个主要模式设置) 中推断出正确的内容,因此它可以插入 HTML 注释,例如。如果它找不到更好的办法,它会退回到#-to-\n注释(如 shell、awk、Perl、tcl 和许多其他 Unix 语言使用的注释)。该命令也足够智能,可以注意到文件中是否已经存在版本控制标头,并会在插入冗余集之前要求您确认。
If you type C-x v h (for vc-insert-headers) while visiting a registered and editable file, VC tries to determine from the syntax of the file how to insert the version control header(s) as a comment and then do so. VC knows about C and Java code, and nroff/troff/groff code especially, and can usually deduce the right thing from Emacs' comment-start and comment-end global variables (set by each major mode) so it can insert HTML comments, for example. It falls back to #-to-\n comments (like those used by shell, awk, Perl, tcl, and many other Unix languages) if it can't figure out anything better to do. This command is also smart enough to notice if you already seem to have version control headers present in the file and will ask you for confirmation before inserting a redundant set.
C 代码的一个特殊行为值得一提。默认情况下,C 文件实际上并不获取放在注释中的版本标头。相反,Emacs 为名为vcid的静态虚拟变量生成字符串初始化。执行此操作后,标头实际上会作为字符串生成到相应的目标文件中,并且您可以使用strings命令(如果您有类 Unix 环境)来查看生成了二进制文件的源版本从。
One special behavior with respect to C code is worth mentioning. C files don't actually get version headers put in comments by default. Instead, Emacs generates a string initialization for a static dummy variable called vcid. This action is taken so the header will actually be generated into the corresponding object file as a string, and you can use the strings command (if you've got a Unix-like environment) to see which versions of its sources a binary was generated from.
项目的快照是一组 项目文件的修订被视为一个单元。通常,发布与项目产品交付给客户或其他外部评估者的时间点相关。
A snapshot of a project is a set of revisions of the project files treated as a unit. Typically, releases are associated with points at which the project's product goes to a customer or other outside evaluator.
当您使用项目文件的子树并想要定义文档或程序的版本时,您可能会发现必须通过记住或存储一长串文件修订号来完成此操作很乏味。因此,大多数版本控制系统使您能够将符号版本名称与构成版本的所有修订版关联起来,然后在稍后命名修订版以供检索或差异报告时使用该符号名称。
When you're working with a subtree of project files and want to define a release of a document or program, you may find it tedious to have to do it by remembering or storing long lists of file revision numbers. Accordingly, most version control systems give you the ability to associate a symbolic release name with all the revisions that make up a release, and then to use that symbolic name later on when naming revisions for retrieval or difference reports.
Bare RCS 和 CVS 都提供此功能。裸 SCCS 没有,但 VC 包含在 SCCS 下模拟它的代码。实际上,本机符号名称和 VC 之间的区别几乎是看不见的。 VC 模拟的唯一缺点是,当您在 VC 外部调用符号名称时,SCCS 工具将不知道它们。 (请注意,这个概念实际上并不适用于 Subversion,因为在该环境中,每个修订版都是构成整个模块的文件和目录的快照。)
Bare RCS and CVS both provide this capability. Bare SCCS does not, but VC includes code to simulate it under SCCS. In practice, the difference between native symbolic names and VC's is next to invisible. The only drawback of VC's simulation is that the SCCS tools won't know about symbolic names when you call them outside VC. (Note that this concept doesn't really apply to Subversion, because in that environment every revision is a snapshot of the files and directories comprising the entire module.)
Cx vs(对于vc-create-snapshot)会提示您输入符号名称。然后,VC 将此名称与当前目录下每个已注册文件的当前修订级别相关联。
The C-x v s (for vc-create-snapshot) prompts you for a symbolic name. VC then associates this name with the current revision level of every registered file under the current directory.
使用vc-create-snapshot创建的符号名称也是任何其他需要修订号的 VC 命令的有效参数。符号名称对于vc-diff特别有用;这意味着您可以将命名版本相互比较或与签出的工作文件进行比较。Cx vr (用于vc-retrieve-snapshot )命令采用符号名称,并以与该名称关联的修订级别检查当前工作目录下的每个已注册文件。
The symbolic names you create with vc-create-snapshot are also valid arguments to any other VC command that wants a revision number. Symbolic names are especially useful with vc-diff; it means you can compare named releases with each other or with your checked-out work files. The C-x v r (for vc-retrieve-snapshot) command takes a symbolic name and checks out every registered file underneath the current working directory at the revision level associated with the name.
如果任何人检出当前目录下的任何注册文件,这两个快照命令都将失败,返回错误并且不标记或检索任何文件。vc-create-snapshot命令失败是为了避免创建快照后检索时无法完全恢复当前状态。它也会失败,以避免在您有机会签入或恢复工作文件更改之前对其进行更改。
Both the snapshot commands will fail, returning an error and not marking or retrieving any files, if any registered file under the current directory is checked out by anyone. The vc-create-snapshot command fails in order to avoid making a snapshot that, when retrieved later, won't restore the current state completely. It also fails in order to avoid stepping on your work file changes before you've had the chance to check them in or revert them out.
命令Cx va(用于vc-update-change-log)帮助 VC 进行一些项目管理 自由软件基金会使用的约定。 FSF 项目通常在每个目录中都有一个名为ChangeLog的文件,该文件应该包含该目录中每个文件的带时间戳的修改注释。从历史上看,ChangeLog提供了更改历史记录或审计跟踪,VC 使用更改注释。
The command C-x v a (for vc-update-change-log) helps VC work with some project-management conventions used by the Free Software Foundation. FSF projects generally have in each directory a file called ChangeLog that is supposed to contain timestamped modification comments for every file in that directory. The ChangeLog, historically, provided the change history, or audit trail, for which VC uses change comments.
VC 提供了一个钩子,可以将最近的更改注释从当前目录下的 master 中复制出来,并以批准的格式将它们附加到ChangeLog中,而不是让您输入两次更改注释(!)。
Rather than make you enter every change comment twice (!), VC provides a hook that copies recent change comments out of masters beneath the current directory and appends them to a ChangeLog in the approved format.
重命名版本控制文件 可能很棘手。在 RCS 或 SCCS 中,您不仅必须重命名工作文件,还要重命名其关联的主文件。在 CVS 下,由于过于神秘的原因而无法在这里讨论,很难在不破坏某些东西的情况下做到这一点。
Renaming version-controlled files can be tricky. In RCS or SCCS, you have to rename not just the work file but its associated master. Under CVS, for reasons too arcane to go into here, it's hard to do at all without breaking something.
vc-rename-file尝试让您了解详细信息,并捕获并通知您可能出现的各种错误情况。它只是提示输入旧文件名和新文件名,尝试做正确的事情,并告诉您是否不能。
The vc-rename-file tries to insulate you from the details and to catch and inform you about various error conditions that can arise. It simply prompts for old and new filenames, tries to do the right thing, and tells you if it cannot.
重命名与 SCCS 下的模拟符号名称功能相互作用很差。这是使用 RCS 或 CVS 的更好理由之一。而且,实际上,如果您认为可能需要重命名或移动文件,那么您最好研究 Subversion,因为它的主要设计目标之一是成为第一个可以轻松完成此任务的版本控制系统。
Renaming interacts badly with the simulated symbolic-name feature under SCCS. This is one of the better reasons to use RCS or CVS. And, actually, if you think you might need to rename or move files, you're best off investigating Subversion since one of its major design goals was to be the first version control system in which this task is straightforward.
所需的文件系统操作确定文件的版本控制状态可能既昂贵又缓慢,尤其是在 NFS 或其他网络环境中。 VC 会付出一些努力来弥补(除非,正如我们稍后将看到的,你告诉它不要这样做)。
The filesystem operations required to determine a file's version control state can be expensive and slow, especially in an NFS or other networked environment. VC goes to some pains to compensate (unless, as we'll see later on, you tell it not to).
它有两种主要方法:(1)在内存中缓存每个文件的信息(例如锁定用户和当前修订号),而不是每次都运行版本控制实用程序将其从相关主文件中解析出来,以及(2)假设它可以从注册文件的写入权限推断其版本控制状态。具体地,VC假定可写的注册文件处于签出并锁定状态,并且不可写的注册文件不是 正在编辑的签出版本。
It has two major methods: (1) caching per-file information (such as the locking user and current revision number) in memory rather than running version control utilities to parse it out of the relevant master every time, and (2) assuming that it can deduce a registered file's version control state from its write permissions. Specifically, VC assumes that a registered file that is writable is in the checked-out-and-locked state and that a registered file that is not writable is not a checked-out version being edited.
多用户环境就是这样,VC 的缓存信息和有关权限的假设有时会导致它走上错误的道路。这种情况几乎总是会发生,因为有人背着VC手动更改了文件的权限。
Multiuser environments being what they are, VC's cached information and assumptions about permissions occasionally lead it down the wrong path. This situation almost always occurs because someone has manually changed a file's permissions behind VC's back.
如果您认为发生了这种情况,请调用vc-clear-context。此命令强制 VC 放弃所有缓存在内存中的有关您正在使用的文件的版本控制状态的假设。
If you think that this situation has occurred, call vc-clear-context. This command forces VC to throw away all its cached-in-memory assumptions about the version control state of the files you are working with.
从理论上讲,VC 也可能会因两个或多个 VC 之间或 VC 与运行裸 SCCS、RCS 或 CVS 实用程序的某人之间的竞争条件而感到困惑。这不仅仅是风险投资的问题;在两个或更多运行裸公用设施的人之间也可能发生同样类型的竞争(尽管可能性较小)。然而,即使在VC,这种竞赛也很少见;作者在数十万程序员工作时间中还没有听说过任何已知发生过这种情况的例子。
It is also theoretically possible for VC to get confused by a race condition between two or more VCs, or between VC and someone running the bare SCCS, RCS, or CVS utilities. This is not just a VC problem; the same sort of race is possible (though less likely) between two or more people running the bare utilities. However, this kind of race is very rare even in VC; the authors haven't heard of any instance in hundreds of thousands of programmer-hours in which it's known to have happened.
如果您担心这个问题,VC 源代码(Emacs Lisp 源目录中的vc.el )包含一条注释,对潜在的多用户冲突和竞争情况进行了仔细而广泛的分析。 VC 与底层实用程序一样安全。
If you're concerned about this issue, the VC source code (vc.el in your Emacs Lisp source directory) includes a comment giving a careful and extensive analysis of potential multiuser conflict and race situations. VC is exactly as safe from them as the underlying utilities can be.
我们之前描述过的一些规则 可以通过设置与 VC 模式相关的某些 Emacs 变量来更改 VC 行为的章节。我们将在这里讨论一些最重要的内容。
Some of the rules we've described earlier in the chapter for VC's behavior can be changed by setting certain Emacs variables related to VC mode. We'll go over a few of the most important here.
该变量控制 VC 使用的版本控制系统集,并且在列表中找到它们的顺序控制着尝试它们的顺序。它默认为(RCS CVS SVN
MCVS SCCS).如果您从列表中删除值,它们将不会被视为可以使用的有效版本控制系统。如果列表为空,则 VC 被完全禁用。
This variable controls the set of version control systems used by VC,
and the order in which they are found in the list controls the order
in which they are attempted. It defaults to (RCS CVS SVN
MCVS SCCS). If you remove values from the list, they
won't be considered valid version control systems to
use. If the list is empty, VC is disabled entirely.
如果该变量非零,则该变量在访问该文件的每个缓冲区的模式行上显示文件的修订号和状态。为了避免主文件的昂贵查询,如果您在非常慢的网络链接上运行 VC,您可能需要关闭此变量。
This variable displays a file's revision number and status on the mode line of each buffer visiting it, if this is non-nil. To avoid expensive queries of the master file, you may want to turn this variable off if you are running VC over very slow network links.
这些变量提供使用指定版本控制系统时由vc-insert-headers插入的标头列表 。例如,CVS 的标头位于变量vc-cvs-header中。如果您喜欢不同的版本号标题格式,您可以自定义这些列表。
These variables provides lists of the headers to be inserted by vc-insert-headers when using the specified version control system. For example, the headers for CVS are in the variable vc-cvs-header. You can customize these lists if you like a different format for your version number headers.
通常,每当执行签入时,VC 都会保留工作文件的只读副本。这个功能很方便,因为它意味着make和其他工具总是能在它们期望的地方找到工作文件。如果磁盘空间非常紧张,可以将其关闭,但是每次除 VC 以外的工具需要工作文件时,您都必须执行显式检出。 (Emacs 本身通过一段始终驻留的 VC 代码了解版本控制;如果需要,它的访问命令会执行签出,而不锁定文件。)
Normally, VC leaves a read-only copy of the work file in place whenever it performs a check-in. This feature is convenient because it means make and other tools always find work files where they expect to. If you're very tight on disk space, you can turn it off, but then you have to execute an explicit check-out every time a tool other than VC needs the work file. (Emacs itself knows about version control through a piece of VC code that's always resident; its visit commands perform a check-out if necessary, without locking the file.)
该变量通常为nil。告诉VC不要信任文件的权限或所有权作为其版本控制状态的指标。此更改会大大减慢 VC 的速度,但如果(例如)您的开发组在多个不同的目录中工作并通过符号链接访问工作文件,则可能有必要。在这种情况下,链接的权限和所有权不传达任何有关工作文件状态的信息。
This variable is normally nil. Make it t to tell VC not to trust a file's permissions or ownership as indicators of its version control state. This change slows VC down a lot, but it may be necessary if (for example) your development group is working in several different directories and accessing work files via symbolic links. In such a case, the permissions and ownership of the link convey nothing about the state of the work file.
该变量默认为nil。如果它非零,它会抑制vc-revert-buffer 在放弃更改之前通常给出的确认提示。
This variable defaults to nil. If it is non-nil, it suppresses the confirmation prompt vc-revert-buffer normally gives you before discarding changes.
大多数版本控制系统允许(但不要求)您在注册文件时输入初始注释 - 更改历史记录的开头。如果此变量非零,则 VC 在注册时会为此注释弹出一个缓冲区,就像在签入时通常为更改注释所做的那样。
Most version control systems allow (but do not require) you to enter an initial comment when you register a file—a lead-off for the change history. If this variable is non-nil, VC pops up a buffer for this comment at registration time just as it normally does for change comments at check-in time.
Emacs diff.el模式在生成更改报告时将命令行开关从此全局变量传递给diff 。 VC 也以同样的方式使用它。它默认使用单个开关-c来强制上下文差异格式;-u表示统一差异格式也相当流行。
The Emacs diff.el mode takes command-line switches from this global variable to pass to diff when generating a change report. VC uses it the same way. It defaults to the single switch -c to force context-diff format; -u for unified-diff format is also fairly popular.
Emacs 在线帮助系统中完整记录了许多其他不太重要的全局变量。
A number of other, less important global variables are fully documented in the Emacs online help system.
VC从一开始就是为了可用而设计的 作为多个版本控制系统的前端。实际运行版本控制工具的代码与用户级包逻辑仔细隔离,这样插入新系统并不困难。 VC的作者最初编写它是为了处理SCCS和RCS;后来由另一个人添加了 CVS 支持,没有太大困难,并且 Subversion 支持是 CVS 代码的一个更简单的变体。
VC was designed from the beginning to be usable as a front-end for multiple version control systems. The code that actually runs the version control tools is carefully isolated from the user-level package logic in such a way that plugging in new systems is not very hard. VC's author originally wrote it to handle SCCS and RCS; CVS support was added later, by a different person, without much difficulty, and Subversion support was an even simpler variant of the CVS code.
对于 ClearCase(一种流行的商业项目管理系统)的用户来说,Emacs 有几个扩展。考虑到 FSF 对非自由软件的敌对态度,该代码是否被 GNU Emacs 发行版接受是另一个问题。到目前为止还没有,但您可以通过互联网获取软件包。在撰写本文时,最佳选择似乎是clearcase.el。第一个实现的作者VC-ClearCase甚至表示他已转向
clearcase.el.当前的下载站点是
http://members.verizon.net/~vze24fr2/EmacsClearCase/。如果您在阅读本文时有所感动,希望谷歌搜索能够引导您走向正确的方向。
There are a couple of extensions to Emacs for users of ClearCase, a
popular commercial project-management system. Whether this code is
accepted into the GNU Emacs distribution, considering the
FSF's hostile attitude towards non-freeware, is
another question. So far they have not been, but you can obtain the
packages over the internet. At the time of this writing, the best
choice appears to be clearcase.el. The author of
the first implementation, VC-ClearCase, has even
stated that he's switched over to
clearcase.el. The current download site is
http://members.verizon.net/~vze24fr2/EmacsClearCase/.
If it's moved by the time you read this, hopefully a
Google search will steer you in the right direction.
那么,当您阅读本书时,您的 VC 可能会很好地处理除我们在此描述的系统之外的其他系统(尽管 CVS 和 Subversion 在可预见的将来可能仍然是最受欢迎的系统)。如果您是一名熟练的 Emacs Lisp 程序员(或想成为一名程序员)并且拥有自己最喜欢的版本控制系统,请务必破解源代码 - 扩展 VC 来使用它,并分享您的结果,以便每个人都受益。
By the time you read this book, then, your VC may well handle additional systems besides the ones we have described here (though CVS and Subversion are likely to remain the most popular ones for the foreseeable future). If you are a skilled Emacs Lisp programmer (or would like to become one) and have your own favorite version control system, by all means hack the source code—extend VC to use it, and share your results so that everyone benefits.
风险投资并不是项目管理问题的全面解决方案。尽管它可以极大地帮助单作者编程或文档维护,并且可以为涉及多个开发人员的中小型项目提供重要帮助,但它本身对于大型多组件、多目录项目来说不一定足够。以下是其对于大型项目的一些更明显的缺陷:
VC is not a total solution to the project-management problem. Although it assists single-author programming or document maintenance greatly and can give vital help on small- to medium-scale projects involving several developers, it's not necessarily adequate by itself for large multiple-component, multiple-directory projects. The following are some of its more obvious deficiencies for larger projects:
它没有与变更请求或问题报告系统集成。
It is not integrated with a change request or problem-report system.
它对项目文件进行分组的唯一方法是按目录子树。此限制可能会给大型多目录项目带来问题,特别是当两个或更多项目需要共享公共库或子树时。
Its only way of grouping project files is by directory subtree. This limitation may create problems for large, multiple-directory projects, especially when two or more need to share a common library or subtree.
您可以在小型项目中解决这些缺陷。变体版本可以通过编译时条件来处理,例如 C 代码中的#ifdef 。变更请求可以单独保存在某种数据库中(例如 FSF 的 GNATS 系统,或 Mozilla 的 Bugzilla)。程序员可以在头脑中携带进行重命名所需的状态,而不会造成中断。
You can work around these deficiencies on small projects. Variant versions might be handled with compile-time conditions, like #ifdefs in C code. Change requests can be kept separately in some kind of database (such as the FSF's GNATS system, or Mozilla's Bugzilla). Programmers can carry around in their heads the state needed to do renames without disruption.
然而,随着项目规模的扩大和复杂性的增加,此类 临时措施越来越无法防止破坏性的摩擦,并因累积的细节而导致死亡。非常大的项目的复杂性控制需要一个从根本上更强大(不幸的是,更多限制和复杂)的支持环境,它超越了版本控制——一个完整的项目管理系统。
As projects scale up in size and intricacy, however, such ad hoc measures increasingly fail to prevent damaging friction and lead to death by accumulated details. Complexity control for very large projects requires a fundamentally stronger (and, unfortunately, more constraining and complex) support environment that goes beyond version control—a full project-management system.
有关项目管理系统中的设计问题的更多信息,请参阅Don Bolinger 和 Tan Bronson (O'Reilly) 所著的《Applying SCCS and RCS》一书的后半部分。
For more on the design issues in project-management systems, see the latter half of the book Applying SCCS and RCS by Don Bolinger and Tan Bronson (O'Reilly).
我们强烈建议那些具有版本控制经验的人注意以下格言:要有效地使用 VC,请尽早并经常检查您的更改!当然,当您作为开发团队的一员工作时,您确实需要注意每次仅签入一致且有效的文件集。没有什么比发现自己无法再编译和测试自己的代码更令人沮丧的了,因为其他人已经签入了他们的零散或损坏的代码。
We urge those of you with prior version control experience to heed the following maxim: to use VC effectively, check in your changes early and often! Of course, when you are working as part of a team of developers, you do need to take care to check in only a consistent and working set of files each time. There's nothing quite equal to the frustration of discovering that you can no longer compile and test your own code because someone else has checked in a fragmentary or broken piece of theirs.
如果您习惯了像裸 SCCS、RCS 或(在较小程度上)CVS 一样笨拙和困难的版本控制界面,您的反应可能会阻止您充分利用 VC。你可能不会经常做出承诺;您不习惯能够立即获取整个文件子树的状态报告。
If you're used to version control interfaces that are as clumsy and difficult as bare SCCS, RCS, or—to a lesser extent—CVS, your reflexes may prevent you from getting the most leverage out of VC. You probably won't commit often; you're not used to being able to instantly get status reports on a whole subtree of files.
值得花一点思考和努力来重新教育自己。您会发现,VC 下的版本控制不是一件烦人的小事,而是可以带来极大的解放。通过经常检查更改,您会发现您可以进行更多实验,因为您将知道如何在需要时快速恢复到已知的良好状态。
It's worth a little thought and effort to reeducate yourself. You'll find that, instead of being an irritating minor chore, version control under VC can be tremendously liberating. By checking changes in often, you'll find you can afford to experiment more, because you'll know how to revert to a known good state quickly if need be.
在使用任何版本控制时 系统中,您有时想要比较文件的不同版本。通常您对当前工作修订版中的更改感兴趣,但有时您需要更多历史信息。当像 CVS 这样的乐观策略被证明是错误的,并且您需要将多个开发人员所做的不兼容的更改合并到文件的同一部分时,就会出现最具挑战性的情况。
In working with any version control system, you sometimes want to compare different revisions of a file. Often you're interested in what's changed in the current working revision, but sometimes you're after more historical information. The most challenging situation arises when an optimistic strategy like CVS is proved wrong, and you need to merge incompatible changes made by multiple developers to the same section of a file.
我们已经描述了vc-diff,它是 VC 的内置工具,可帮助完成这些任务。然而,如果我们没有向您介绍 Ediff,那就是我们的失职了,Ediff 是当前版本的 GNU Emacs 中提供的一个更强大的工具。埃迪夫非常富有;它几乎感觉就像另一个程序“接管”了你的 Emacs 会话一段时间。全面的覆盖需要一整章,甚至可能需要单独的手册,但本介绍将帮助您入门,并为您指明内置手册(如果您想深入研究)。
We've already described vc-diff, VC's built-in facility for helping with these tasks. We would be remiss, however, if we did not introduce you to Ediff, an even more powerful facility that is available in current releases of GNU Emacs. Ediff is extremely rich; it almost feels like another program that "takes over" your Emacs session for a while. Full coverage would require an entire chapter, or perhaps even its own handbook, but this introduction will get you started and point you at the built-in manual if you want to delve deeper.
在大多数情况下,您启动 Ediff 作为一个独立的实体,而不是由版本控制接口自动调用。例外情况(如上所述)是,如果您在签入操作期间发生冲突时请求 Emacs 帮助解决冲突,或者在访问包含此类冲突的缓冲区时手动调用vc-resolve-conflicts 。
For the most part, you launch Ediff as an independent entity rather than having it invoked automatically by the version control interface. The exception (as mentioned above) is if you ask Emacs for help resolving conflicts when they occur during a check-in operation or manually invoke vc-resolve-conflicts while visiting a buffer containing such conflicts.
如果要使用 Ediff 比较文件的两个不冲突修订版,请选择“工具” → “比较 (Ediff)” →“带修订版的文件”,或键入Mx ediff-revision Enter。 Ediff 会提示您要比较的文件(默认为与当前缓冲区关联的文件)以及要比较的修订版本,默认为上次签入的版本和当前状态缓冲。 (Ediff 还可以用于版本控制系统上下文之外的许多任务;您可能想在雨天探索“比较 (Ediff)”菜单上的选项。)
If you want to use Ediff to compare two nonconflicting revisions of a file, choose Tools → Compare (Ediff) → File with revision, or type M-x ediff-revision Enter. Ediff prompts you for the file you'd like to compare (defaulting to the file associated with the current buffer), and the revision(s) you'd like to compare, defaulting to the version last checked in and the current state of the buffer. (Ediff can also be used for many tasks outside the context of version control systems; you might want to explore the options on the Compare (Ediff) menu on a rainy day.)
第一次调用 Ediff 时,您可能会发现它令人迷惑。除了显示正在比较的两个文件或修订版本的预期缓冲区对之外,它还会弹出一个小的“控制窗口”(参见图 12-4),您可以在其中键入命令。在其默认配置中,这是一个单独的操作系统窗口(或者 Emacs 称为“框架”)。为了使 Ediff 命令发挥作用,该窗口必须具有键盘焦点(就操作系统而言,必须显示为当前活动窗口)。这与 Emacs 中的几乎任何其他情况不同,因为您在一个框架中查看和操作内容,而第二个框架具有焦点。
The first time you invoke Ediff, you will probably find it disorienting. In addition to the expected pair of buffers showing you the two files or revisions being compared, it pops open a small "control window" (see Figure 12-4) in which you type commands. In its default configuration, this is a separate operating system window (or what Emacs refers to as a "frame"). For Ediff commands to work, this window must have keyboard focus (must show as being the currently active window as far as the operating system is concerned). This is different from almost any other situation in Emacs, in that you're looking at and manipulating content in one frame while a second frame has focus.
图 12-4。 Ediff 控制窗口处于默认状态 (Mac OS X)
Figure 12-4. The Ediff control window in its default state (Mac OS X)
在默认配置中,控制窗口设计得足够小,不会妨碍较小的显示器。问题是您可能甚至没有注意到它,更不用说意识到它的用途了!除了作为您输入 Ediff 命令的地方之外,这个小窗口还显示您在差异列表中的位置(在本例中,在七个差异中的第一个之前),并提醒您可以输入?以获得更多帮助。作为 Ediff 新用户,我们强烈建议您输入?每次启动时,控制窗口都会展开到更大的快速帮助模式,如图12-5所示。
In its default configuration, the control window is designed to be small enough not to get in the way on smaller displays. The problem is that you might not even notice it, let alone realize what it's for! In addition to being the place you type Ediff commands, this small window shows you where you are in the difference list (in this case, before the first of seven differences), and reminds you that you can type ? to get some more help. As a new Ediff user, we strongly recommend that you type ? each time you fire it up to expand the control window into the larger, Quick Help mode, shown in Figure 12-5.
图 12-5。显示快速帮助的 Ediff 控制窗口 (Mac OS X)
Figure 12-5. The Ediff control window showing Quick Help (Mac OS X)
除了控制窗口之外,您还将看到您之前用于编辑的框架内正在比较的文件之间的差异。如果您正在查看一个大文件,最初可能看不出任何差异。您可以按照快速帮助窗口的建议,通过键入n或按空格键跳转到第一个差异。 (请记住,要使任何 Ediff 命令起作用,控制/快速帮助窗口 必须具有键盘焦点。)显示的差异将类似于图 12-6。
In addition to the control window, you'll see the differences between the files you're comparing inside the frame you were previously using for editing. If you're looking at a large file, none of the differences might be visible initially. You can jump to the first difference by typing n or pressing the space bar, as suggested by the quick help window. (Remember that for any of the Ediff commands to work, the control/quick help window must have keyboard focus.) The displayed differences will look something like Figure 12-6.
Ediff 将每个缓冲区中的差异区域居中,并用颜色标记更改的行,进一步强调已更改的行的特定部分,以帮助吸引视觉注意差异。这比传统的 diff 模式更有帮助,因此值得学习这个奇怪的新界面。
Ediff centers the difference regions within each buffer, and marks the changed lines with color, further emphasizing the specific portions of the lines which have changed to help attract visual attention to the differences. This is much more helpful than the traditional diff mode, making it worthwhile learning the strange new interface.
使用 Ediff 的基本方法是滚动缓冲区,查看它们之间发生了什么变化。普通的 Emacs“浏览”键(空格键向前移动,Del向后移动)被绑定在控制窗口中,带您一一浏览差异。按 n(下一个)和p(上一个)具有相同的效果。如果您想转到特定差异处,可以键入一个数字,后跟 j(跳转)以立即移至该差异处。要按页面而不是按差异向上或向下滚动,可以使用v向前移动,使用 V向后移动。如果缓冲区包含宽行,您还可以键入<和> 左右滚动。如果您想并排查看缓冲区而不是一个在另一个之上,请输入|(竖线)。第二次键入此命令将返回到垂直显示缓冲区。为了减少水平滚动的需要,您可以通过键入m使比较窗口尽可能宽(这也是一个切换;再次键入它会将窗口恢复到之前的宽度)。此命令可能会导致控制窗口失去焦点,迫使您在发出下一个 Ediff 命令之前单击回该窗口。 (请参阅本章后面的“从混乱中恢复”。) 重要 表 12-2总结了 Ediff 中可用的命令。
The basic way to use Ediff is to scroll through the buffers, seeing what has changed between them. The normal Emacs "browsing" keys (Space to move forward, Del to move backward) are bound in the control window to take you through the differences one by one. Pressing n (next) and p (previous) has the same effect. If you want to go to a specific difference, you can type a number followed by j (jump) to move immediately to that difference. To scroll up or down by pages rather than by differences you can use v to move forward and V to move backward. If your buffers contain wide lines, you can also type < and > to scroll left and right. If you'd like to view the buffers side by side rather than one above the other, type | (vertical bar). Typing this a second time returns to showing the buffers vertically. To reduce the need to scroll horizontally, you can make the comparison window as wide as possible by typing m (this is also a toggle; typing it again returns the window to its previous width). This command might cause the control window to lose focus, forcing you to click back into it before issuing the next Ediff command. (See "Recovering from Confusion" later in this chapter.) Important commands available in Ediff are summarized in Table 12-2.
表 12-2。 Ediff命令
Table 12-2. Ediff commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
空格或n Space or n |
ediff-下一个差异 ediff-next-difference |
移至文件之间的下一个差异。 Move to the next difference between the files. |
|
德尔或p Del or p |
ediff-前一个差异 ediff-previous-difference |
移至文件之间的先前差异。 Move to the preceding difference between the files. |
|
j j |
ediff 跳转到差异 ediff-jump-to-difference |
转到指定为数字前缀参数的差值。 Go to the difference specified as a numeric prefix argument. |
|
v或Cv v or C-v |
ediff 垂直滚动 ediff-scroll-vertically |
在两个缓冲区中向前移动一页。 Move forward one page in both buffers. |
|
V或Mv V or M-v |
ediff 垂直滚动 ediff-scroll-vertically |
在两个缓冲区中向后移动一页。 Move backward one page in both buffers. |
|
< < |
ediff 水平滚动 ediff-scroll-horizontally |
将每个缓冲区向左滚动。 Scroll each buffer to the left. |
|
> > |
ediff 水平滚动 ediff-scroll-horizontally |
将每个缓冲区向右滚动。 Scroll each buffer to the right. |
|
|(竖线) | (vertical bar) |
ediff-切换-分割 ediff-toggle-split |
在查看缓冲区上下切换和并排查看缓冲区之间切换。 Switch between viewing the buffers one above the other and side-by-side. |
|
米 m |
ediff-切换宽显示 ediff-toggle-wide-display |
在正常框架大小和使其尽可能宽之间切换。 Toggle between normal frame size and making it as wide as possible. |
|
A a |
ediff-复制 A 到 B ediff-copy-A-to-B |
将缓冲区 A 中找到的当前差异的版本复制到缓冲区 B。 Copy the version of the current difference found in buffer A to buffer B. |
|
乙 b |
ediff 复制 B 到 A ediff-copy-B-to-A |
将缓冲区 B 中找到的当前差异的版本复制到缓冲区 A。 Copy the version of the current difference found in buffer B to buffer A. |
|
ra或rb r a or r b |
ediff-恢复-差异 ediff-restore-diff |
将缓冲区 A(或 B)中的当前差异恢复到从其他缓冲区复制之前的状态。 Restore the current difference in buffer A (or B) to the way it was before copying from the other buffer. |
|
甲或乙 A or B |
ediff 切换只读 ediff-toggle-read-only |
将指定的缓冲区切换为(或退出)只读模式。 Switch the specified buffer into (or out of) read-only mode. |
|
ga或g b g a or g b |
ediff 跳转到点差异 ediff-jump-to-difference-at-point |
将比较缓冲区重新放置在指定缓冲区中最接近当前位置(点)的差异上。 Recenter the comparison buffers on the difference nearest to your current location (point) in the specified buffer. |
|
氯 C-l |
ediff-recenter ediff-recenter |
恢复比较显示,使所有正在比较的缓冲区的突出显示区域都可见;如果您一直在做其他事情并想重新进行比较,那么这很有用。 Restore the comparison display so that the highlighted regions of all buffers being compared are visible; useful if you've been doing something else and want to get back to comparing. |
|
! ! |
ediff-更新-差异 ediff-update-diffs |
重新计算并重新显示突出显示的区域;如果您手动对缓冲区进行了大量更改,则非常有用。 Recalculate and redisplay the highlighted regions; useful if you've manually made extensive changes to a buffer. |
|
wa或w b w a or w b |
ediff 保存缓冲区 ediff-save-buffer |
将指定的缓冲区保存到磁盘。 Save the specified buffer to disk. |
|
乙 E |
ediff-文档 ediff-documentation |
打开 Ediff 的手册。 Open the manual for Ediff. |
|
z z |
ediff-暂停 ediff-suspend |
关闭 Ediff 控制窗口,但使会话保持活动状态,以便稍后恢复。 Close the Ediff control window, but leave the session active so you can resume it later. |
|
q q |
ediff-退出 ediff-quit |
关闭 Ediff 窗口并结束本次比较会话。 Close the Ediff window and end this comparison session. |
除了简单地
查看文件之间的差异,您有时会想要解决或合并它们(特别是如果您由于签入文件修订时发生冲突而输入了 Ediff)。有几个命令可以帮助解决此问题,它们通常要求您选择要使用的缓冲区。正如您可能在图 12-5中注意到的那样,Ediff 为每个文件或修订缓冲区分配一个字母来标识它:A,
B有时C如果您要比较三件事。许多 Ediff 命令都使用这些缓冲区标识符 -X对于大多数使用它们的命令,该字母在快速帮助窗口中用于代表这些标签。
In addition to simply
viewing the differences between files, you will sometimes want to
resolve or merge them (especially if you've entered
Ediff as the result of conflicts that occurred while checking in a
file revision). Several commands help with this, and they generally
require you to choose which buffer you want to work from. As you
might have noticed in Figure 12-5, Ediff assigns each file or
revision buffer a letter to identify it: A,
B and sometimes C if you are
comparing three things. A number of Ediff commands work with these
buffer identifiers—the letter X is used to
stand for these labels in the quick help window for most commands
that use them.
要将在一个缓冲区中找到的当前差异的版本复制到另一缓冲区,请键入分配给具有“正确”版本的缓冲区的字母。例如,要将A的版本复制到
B,请键入a。 Ediff 进行了此更改,但会跟踪您更改的缓冲区中的旧值。在我们的示例中,如果
B像这样更改缓冲区后,您改变主意并想要恢复其旧状态,则可以键入r
b(“恢复缓冲区
B”)。这些更改会逐一进行跟踪,因此您不必立即改变主意;只要您仍在同一个 Ediff 会话中,您就可以跳回到该差异并稍后恢复它。
To copy the version of the current difference found in one buffer to
the other buffer, type the letter assigned to the buffer with the
"right" version. For example, to
copy A's version to
B, type a. Ediff
makes this change but keeps track of the old value in the buffer you
changed. Following along in our example, if after changing buffer
B like this, you change your mind and want to
restore its old state, you can type r
b (for
"restore buffer
B"). These changes are kept track
of on a difference-by-difference basis, so you don't
have to change your mind right away; you can jump back to that
difference and restore it at a later time, as long as
you're still in the same Ediff session.
当然,要更改缓冲区,它不能处于只读模式。如果您将当前文件与历史修订版本进行比较,则代表旧版本的缓冲区是只读的,因为您无法更改过去的版本。如果您想避免在浏览差异时意外更改文件,可以通过键入Shift和缓冲区的字母标签将其缓冲区变为只读。 (Shift-b使缓冲区
B只读)。这是一个切换,因此再次执行此操作会使只读缓冲区可编辑。如果您对代表历史修订版的缓冲区执行此操作,尽管 Emacs 将允许您编辑该缓冲区,但您实际上不会影响版本控制系统中的修订版。因此,除非您试图让自己感到困惑,否则我们建议您避免这种做法。
Of course, to make changes to a buffer, it cannot be in read-only
mode. If you are comparing a current file with a historical revision,
the buffer representing the older version is read-only because you
can't change the past. If you want to avoid
accidentally changing a file while browsing differences, you can
cause its buffer to become read-only by typing Shift and the buffer's letter
label. (Shift-b to make buffer
B read-only). This is a toggle, so doing it again
makes a read-only buffer editable. If you do this to a buffer
representing a historical revision, although Emacs will then let you
edit the buffer, you're not actually affecting the
revision within the version control system. So unless
you're trying to confuse
yourself, we'd suggest avoiding this practice.
如果您正在浏览缓冲区,通过选择要在 Ediff 控制窗口中使用的适当版本来进行许多更改,您可能会发现自己想要保存一个或另一个差异缓冲区。虽然您当然可以单击差异窗口,移至该缓冲区,然后使用标准 Cs命令进行保存,但 Ediff 提供了更方便的替代方案。只需按w(写入),然后按缓冲区的字母标签即可保存该缓冲区,而无需离开控制窗口。
If you're whipping through the buffers, making many changes by selecting appropriate versions to use within the Ediff control window, you may find yourself wanting to save one or the other of your difference buffers. While you can certainly click over to the difference window, move into that buffer, and use the standard C-s command to save, Ediff offers a more convenient alternative. Simply press w (write) followed by the buffer's letter label to save that buffer without leaving the control window.
当你完成比较后 关闭控制窗口并返回“正常”Emacs 世界的最快方法是输入 q退出 Ediff 会话。在确认您确实想要执行此操作后,Ediff 会关闭控制窗口并自行清理。您还可以通过键入z来暂时暂停会话。这将关闭 Ediff 控制窗口,但 Ediff 会记住您正处于会话中,您可以稍后随时返回该会话。最简单的方法是通过选择“工具” → “Ediff 杂项” → “列出 Ediff 会话”来查看活动 Ediff 会话的列表。当您实际退出 Ediff 会话时,它不再出现在此列表中。
When you're done comparing the files, the quickest way to close the control window and get back to the "normal" Emacs world is to type q to quit your Ediff session. After confirming that you really want to do this, Ediff closes the control window and cleans up after itself. You can also suspend the session temporarily by typing z for suspend. This closes the Ediff control window, but Ediff remembers that you were in the middle of a session, to which you can return later whenever you'd like. The easiest way to do this is to view the list of active Ediff sessions by choosing Tools → Ediff Miscellanea → List Ediff Sessions. When you actually quit an Ediff session, it no longer appears in this list.
如果您一直在 Ediff 中浏览,突然发现您的命令不起作用,您可能不小心单击了差异窗口并直接在其中一个缓冲区中键入,或者您可能使用了切换窗口的 Ediff 命令出乎意料地关注你。确保撤消您输入到比较缓冲区中的杂散字符,然后单击控制窗口并再次开始发出命令。
If you've been cruising along in Ediff and suddenly find your commands aren't working, you've probably accidentally clicked on the differences window and are typing in one of the buffers directly, or perhaps you used an Ediff command that switched the window focus on you unexpectedly. Make sure to undo the stray characters you've typed into the comparison buffer, then click on the control window and start issuing commands again.
当然,当您注意到想要进行的更改时,您可能想要有意地跳转到编辑缓冲区之一。您可以随时这样做;当您想要移动到其他差异或使用其他 Ediff 命令时,请记住切换回控制窗口。如果在编辑一个比较缓冲区一段时间后,您想返回查看差异,请从最接近编辑位置的差异开始,单击控制窗口并键入g, 然后键入分配给该缓冲区的字母您感兴趣的内容(如前面“进行更改”中所述)。
Of course, you may want to intentionally jump over to edit one of the buffers as you notice changes you'd like to make. You can do that at any time; just remember to switch back to the control window when you want move to other differences or use other Ediff commands. If, after editing one of the comparison buffers for a while, you'd like to return to viewing differences, starting with the difference nearest to your edit location, click in the control window and type g followed by the letter assigned to the buffer in which you're interested (as discussed earlier in "Making Changes").
如果您通过直接编辑缓冲区进行了实质性更改,您可能会发现差异区域突出显示与差异的实际位置不同步。要解决此问题,一旦控制窗口获得焦点,请键入!导致 Ediff 重新计算并重新显示差异。
If you've made substantial changes by editing the buffer directly, you may find that the difference region highlights have drifted out of synch with the actual location of differences. To fix this, once the control window has focus, type ! to cause Ediff to recalculate and redisplay the differences.
如果您已经重新配置了您正在查看的缓冲区(也许您想查找一些帮助文本,或者从事一项辅助任务,Emacs 当然鼓励这样做),您可以通过单击控制窗口并恢复 Ediff 的窗口配置键入Cl(重新居中)。这将设置比较窗口来显示您正在比较的文件,并将当前差异集中在每个缓冲区中。您可能会发现它还会导致比较窗口获得键盘焦点,因此在尝试发出任何 Ediff 命令之前,请务必在必要时单击控制窗口。
If you've reconfigured the buffers you're looking at (perhaps you wanted to look up some help text, or engage in a side task, which Emacs certainly encourages) you can restore the window configuration for Ediff by clicking on the control window and typing C-l (recenter). This sets up the comparison window to display the files you're comparing and centers the current difference in each buffer. You may find that it also causes the comparison window to get keyboard focus, so be sure to click on the control window if necessary before you try to issue any Ediff commands.
如前所述,Ediff 的内容远远超出我们在此讨论的范围。当您想探索它时,内置的 Ediff 手册是一个很好的起点。您可以通过在 Ediff 控制窗口中键入E(Shift-e,大小写很重要)来实现此目的。如果您尚未进入 Ediff,可以选择“工具” → “Ediff 杂项” → “Ediff 手册”,或者可以通过输入Ch i来调用 Emacs 文档浏览器 Info ,然后从主题主菜单中选择 Ediff。 (输入m作为菜单,然后按e d Enter足以完成“Ediff”并跳转到其手册。)
As noted, there is a whole lot more to Ediff than we can discuss here. When you want to explore it, a good starting place is the built-in Ediff manual. You can get to this by typing E (Shift-e, the capitalization matters) in the Ediff control window. If you're not already inside Ediff, you can choose Tools → Ediff Miscellanea → Ediff Manual, or you can invoke Info, the Emacs documentation browser, by typing C-h i, and choose Ediff from the main menu of topics. (Typing m for menu, followed by e d Enter is enough to complete "Ediff" and jump to its manual.)
要获得更多特定于任务的帮助,您可以使用鼠标中键单击快速帮助窗口中的任何命令,以获取描述其功能的帮助。 (如果您没有三键鼠标,则可以使用常规鼠标按钮单击该命令,然后按 Enter。)
For more task-specific help, you can click on any of the commands in the quick help window using your middle mouse button to get help describing what it does. (If you lack a three button mouse, you can click on the command with your regular mouse button and then press Enter.)
现在应该来了 毫不奇怪,您可以更改 Ediff 工作方式的许多细节,使其更好地适合您的思维和工作方式。在你很好地掌握了基础知识之后,你可以使用第 10 章中描述的自定义工具来调整 Ediff 的工作方式,方法是选择“工具” → “Ediff 杂项” → “自定义 Ediff”。如果对控制窗口使用单独的操作系统窗口(框架)让您抓狂,您可以通过选择“工具” → “Ediff 其他” → “切换使用单独的控制缓冲区框架”来立即切换该行为。
By now it should come as no surprise that you can change many details about the way that Ediff works so it better fits your way of thinking and working. After you've got a good grasp of the basics, you can use the Custom facility described in Chapter 10 to tweak the way Ediff works by choosing Tools → Ediff Miscellanea → Customize Ediff. If the use of a separate operating system window (frame) for the control window is driving you batty, you can toggle that behavior right away by choosing Tools → Ediff Miscellanea → Toggle use of separate control buffer frame.
如果 Ediff 如此强大,为什么它不是vc-diff命令使用的默认模式?最可能的解释是历史原因。vc-diff 的存在时间比 Ediff 还要长,如果一个奇怪的新界面意外地强加给 Emacs 的长期用户,那么他们将会受到干扰。似乎人们正在编写补丁来将 Ediff 与 VC 更紧密地集成,但它们(还?)不是 Emacs 发行版的一部分。如果您对这些工作的当前状态感兴趣,请尝试在 Google 中搜索“vc ediff”。
If Ediff is so powerful, why isn't it the default mode used by the vc-diff command? The most likely explanation is historical; vc-diff has been around longer than Ediff, and it would have been disruptive to long-standing users of Emacs if a strange new interface was unexpectedly foisted on them. It seems people are writing patches to integrate Ediff more tightly with VC, but they are not (yet?) part of the Emacs distribution. If you're interested in the current state of any of these efforts, try a Google search for "vc ediff."
在本章中,我们描述在 Unix、Mac OS X 和 Windows 上安装 Emacs 以及在后两个平台上运行 Emacs 的一些微妙之处。
In this chapter, we describe installing Emacs on Unix, Mac OS X, and Windows as well as some of the subtleties of running Emacs on the latter two platforms.
Emacs 21 可以在免费的 Unix 系统(包括 Linux 和 BSD 变体)以及商业 Unix 版本(例如 AIX、Solaris、SunOS 和 Ultrix)上运行。它在 Mac OS X 上运行(目前是一个单独的分支,但从 21.4 开始将被合并到主发行版中)。它可以在 Windows 甚至 MS-DOS 上运行。您仍然可以获得 Mac OS 8/9 和 Amiga(仅举几例)的端口。 Emacs 是真正的多平台编辑器。
Emacs 21 runs on free Unix systems including Linux and BSD variants as well as on commercial Unix versions such as AIX, Solaris, SunOS,` and Ultrix. It runs on Mac OS X (currently a separate fork, but due to be folded into the main distribution starting with 21.4). It runs on Windows and even on MS-DOS. You can still get ports for Mac OS 8/9 and Amiga (to name only a few). Emacs is truly a multiplatform editor.
我们介绍了在 Unix、Mac OS X 和 Windows 上安装 Emacs。对于 Windows 和 Mac OS X,可以使用预构建的二进制文件。您可能需要从源代码构建 Emacs 以获得最新版本。不过,我们在网上找到了适用于 Windows 和 Mac OS X 的最新二进制文件;你只需要在网上搜寻就能找到它们。当您阅读本文时,我们引用的二进制文件的来源可能已经过时。在这种情况下,请查看本书的网站以获取更新的链接(http://www.oreilly.com/catalog/gnu3)。
We cover installing Emacs on Unix, Mac OS X, and Windows. For Windows and Mac OS X, prebuilt binaries are available. You may want to build Emacs from source in order to obtain the latest version. However, we have found up-to-date binaries online for Windows and Mac OS X; you just have to scout around on the Net to find them. By the time you read this, the sources for the binaries that we cite may be out of date. Check out this book's web site for updated links in that case (http://www.oreilly.com/catalog/gnu3).
一个相关的问题是从哪里获取 Emacs。自由软件基金会 (FSF) 是 Emacs 的官方来源,但与大多数 Emacs 一样 软件组织中,官方发布的版本少之又少。通常,从 CVS 源代码构建 Emacs 是获得前沿版本的最佳方式。只有您可以决定是否愿意拥有最新功能(以及一些错误)或从 FSF 网站下载经过验证的版本。
A related issue is where to get Emacs. The Free Software Foundation (FSF) is the official source for Emacs, but like most software organizations, official releases are few and far between. Often, building Emacs from CVS sources is the best way to get a leading-edge version. Only you can decide whether you would rather have the latest features—along with some bugs—or download the tried-and-true version from the FSF's site.
Emacs 最初构建 在 Unix 系统上,并继续在众多 Unix 变体上运行。我们将下载最新的源代码并向您展示如何从头开始构建 Emacs。这实际上并没有那么难,而且它具有让您及时了解未来版本的有益效果。
Emacs was originally built on a Unix system and continues to run on the multitude of Unix variants out there. We're going to download the latest source and show you how to build Emacs from scratch. It's not really that hard and it has the salutary effect of keeping you up-to-date with future releases.
如果您等不及,请查看主要来源 下载 Emacs 的地址是http://ftp.gnu.org/pub/gnu/emacs/。或者,您可以使用 CVS 来获取绝对最新的版本。但稍后会详细介绍。
If you can't wait, the primary source for downloading Emacs is http://ftp.gnu.org/pub/gnu/emacs/. Alternatively, you can use CVS to nab the absolute latest build. But more on that in a minute.
您可以从任何一处获得 Emacs 许多站点 - 只要您的互联网连接速度足够快,可以轻松传输 20 MB 的文件。您还必须至少有 120 MB 的可用磁盘空间;在未来的 Emacs 版本中,这个数字肯定会增长。
You can get Emacs from any one of many sites—as long as your Internet connection is fast enough to transfer a 20 MB file easily. You must also have at least 120 MB of disk space free; this number will certainly grow in future Emacs releases.
自由软件基金会维护着所有镜像站点的明确列表。 FSF 是 GNU 项目的主要赞助商,项目就设在他们的所在地。如果您想四处看看, 可以从http://www.gnu.org/开始。或者如前所述,您可以直接跳转到位于http://ftp.gnu.org/pub/gnu/emacs/的 Emacs 直接列表。您应该看到类似于图 13-1 的列表。
The Free Software Foundation maintains a definitive list of all mirror sites. The FSF is the principal sponsor of the GNU Project and it is housed at their site. If you want to look around a bit, http://www.gnu.org/ is the place to start. Or as mentioned earlier, you can just jump directly to the directly listing for Emacs at http://ftp.gnu.org/pub/gnu/emacs/. You should see a list similar to Figure 13-1.
查找最新版本的 Emacs(图 13-1中的 21.3 )并下载。
Look for the latest version of Emacs (21.3 in Figure 13-1) and download it.
无论你去哪里获取 来源(将下载的文件放置在何处)实际上取决于您。对于我们基于 Unix 的系统,我们将所有内容下载到 /usr/local/install中。这是一个很好的起点,但如果您有最喜欢的下载/开发区域,请随意使用它。事实上,您甚至可以在构建内容时将所有内容放入主目录中。
Regardless of where you go to get the source, where you put the files you download is really up to you. For our Unix-based systems, we downloaded everything into /usr/local/install. This is a fine place to start, but if you have a favorite download/development area, feel free to use that. In fact, you can even put everything in your home directory while you're building things.
唯一要记住的是,构建过程涉及大量文件,在完成所有操作后您将不再需要这些文件。确保你把东西放在容易清理的地方。
The only thing to remember is that the build process involves a lot of files that you won't need after everything's done. Make sure you put things somewhere that's easy to clean up when all is said and done.
至于可执行文件的最终目的地,这也取决于您。大多数 Unix 系统(包括 Mac OS X)都可以很好地使用/usr/local 层次结构。该目录是常见的,也是构建脚本中的默认选择。不过,如果您所在的机器不是您可以完全控制的,那么您当然可以将 Emacs 安装到您的主目录(或者您为自己的软件保留的子目录)中。
As for the final destination of the executable, that's also up to you. Most Unix systems (including Mac OS X) will do well to use the /usr/local hierarchy. That directory is both common and the default choice in the build scripts. If you're not on a machine that you have complete control over, though, you can certainly install Emacs into your home directory (or a subdirectory you keep for you own software).
关于使用 Emacs 可执行版本的主目录的一个快速说明:如果您升级系统,它确实可以轻松备份 Emacs 或将其转移到另一台计算机(我们从经验中知道!)。但是,它可以限制谁可以访问 Emacs。如果另一个用户在同一台计算机上工作并且你们都想使用 Emacs,那么安装到公共目录(如 /usr/local)绝对是最佳选择。
One quick note on using your home directory for the executable version of Emacs: it does make it easy to back up Emacs or transfer it to another machine if you upgrade your system (we know from experience!). However, it can limit who has access to Emacs. If another user works on the same machine and you both want to use Emacs, installing to a common directory (like /usr/local ) is definitely the way to go.
现在您已经有了文件,您需要
在实际构建 Emacs 之前,需要对其执行两件事:解压缩和解包。您可以使用tar
命令来执行这两项操作。确保您位于下载 Emacs 文件的目录中。键入以下命令(将 更改为
n与您下载的文件匹配的版本号),您将看到文件列表。
Now that you have the file, you need
to
do two things to it before you can actually build Emacs: uncompress
and unpack. You can use the tar
command to do both. Make sure you are in the directory where you
downloaded the Emacs file. Type the following command (changing the
n to the version number that matches the
file you downloaded), and you will see a list of files.
$ tar xvzf emacs-21 . .tar.gzn
x emacs-21.3,0 字节,0 个磁带块
x emacs-21.3/AUTHORS,77854 字节,153 个磁带块
x emacs-21.3/FTP,8950 字节,18 个磁带块
x emacs-21.3/INSTALL,42841 字节,84 个磁带块
x emacs-21.3/README,4046 字节,8 个磁带块
x emacs-21.3/BUGS,1042 字节,3 个磁带块
x emacs-21.3/move-if-change,129 字节,1 个磁带块
x emacs-21.3/ChangeLog,161418 字节,316 个磁带块
x emacs-21.3/Makefile.in,25461 字节,50 个磁带块
。 。 。$ tar xvzf emacs-21.n
.tar.gz
x emacs-21.3, 0 bytes, 0 tape blocks
x emacs-21.3/AUTHORS, 77854 bytes, 153 tape blocks
x emacs-21.3/FTP, 8950 bytes, 18 tape blocks
x emacs-21.3/INSTALL, 42841 bytes, 84 tape blocks
x emacs-21.3/README, 4046 bytes, 8 tape blocks
x emacs-21.3/BUGS, 1042 bytes, 3 tape blocks
x emacs-21.3/move-if-change, 129 bytes, 1 tape blocks
x emacs-21.3/ChangeLog, 161418 bytes, 316 tape blocks
x emacs-21.3/Makefile.in, 25461 bytes, 50 tape blocks
. . .这个创建的文件列表持续了很长一段时间——Emacs 21.3 超过 2500 个文件。如果您不想查看该列表,请从tar命令中省略v(详细选项)。当此命令完成后,您就拥有了 Emacs 的所有文件。
This list of created files goes on for quite a while—over 2500 files for Emacs 21.3. If you don't want to see the list, omit the v (verbose option) from the tar command. When this command completes, you have all of the files for Emacs.
现在所有必要的准备工作都已完成,您可以完成构建和安装 Emacs 本身的步骤。
Now that any necessary preparations are out of the way, you can go through the steps to build and install Emacs itself.
正如我们前面提到的, 您还可以使用 CVS拉取源文件。 CVS 的一大优势是您可以获得绝对最新的版本。
As we mentioned earlier, you can also use CVS to pull the source files. The big advantage with CVS is that you get the absolute latest version.
创建或切换到可以保留 Emacs 构建的目录。不要在临时目录中执行此操作,除非您不打算保留 Emacs。到达那里后,设置CVS_RSH环境变量:
%setenv CVS_RSH sshCreate or switch to a directory where your Emacs build can remain. Don't do this in a temporary directory unless you don't plan on keeping Emacs around. Once there, set up the CVS_RSH environment variable:
% setenv CVS_RSH ssh如果setenv命令无法识别,您可能正在运行bash而不是csh派生的 shell。在这种情况下,请对环境变量使用以下命令。
$export CVS_RSH="ssh"If the setenv command is not recognized, you're probably running bash instead of a csh-derived shell. In that case, use the following command for the environment variable.
$ export CVS_RSH="ssh"使用cvs命令获取源代码。
%cvs -z3 -d:ext:anoncvs@savannah.gnu.org:/cvsroot/emacs co emacs
无法确定主机“savannah.gnu.org (199.232.41.3)”的真实性。
RSA 密钥指纹为 80:5a:b0:0c:ec:93:66:29:49:7e:04:2b:fd:ba:2c:d5。
您确定要继续连接吗(是/否)?Use the cvs command to grab the source code.
% cvs -z3 -d:ext:anoncvs@savannah.gnu.org:/cvsroot/emacs co emacs
The authenticity of host 'savannah.gnu.org (199.232.41.3)' can't be established.
RSA key fingerprint is 80:5a:b0:0c:ec:93:66:29:49:7e:04:2b:fd:ba:2c:d5.
Are you sure you want to continue connecting (yes/no)?验证公钥是否与此密钥匹配:
80:5a:b0:0c:ec:93:66:29:49:7e:04:2b:fd:ba:2c:d5
Verify that the public key matches this key:
80:5a:b0:0c:ec:93:66:29:49:7e:04:2b:fd:ba:2c:d5
这只是确保您确实连接到了正确的系统,并且不会被提供一些恶意的替代方案。
That just makes sure you actually got connected to the right system and aren't being fed some malicious alternative.
如果按键匹配,请输入yes并按Enter。
警告:永久添加“savannah.gnu.org,199.232.41.3” (RSA) 到已知主机列表。 cvs 服务器:更新 emacs u emacs/.cvsignore U emacs/作者 U emacs/错误 U emacs/复制 U emacs/更改日志 emacs/FTP u emacs/安装 ...
If the keys match, type yes and press Enter.
Warning: Permanently added 'savannah.gnu.org,199.232.41.3' (RSA) to the list of known hosts. cvs server: Updating emacs U emacs/.cvsignore U emacs/AUTHORS U emacs/BUGS U emacs/COPYING U emacs/ChangeLog U emacs/FTP U emacs/INSTALL ...
您会看到数千个文件名飞过。如果网络连接速度较慢,此过程可能需要一段时间。不过,请坚持住 — 您即将构建绝对最新版本的 Emacs!
You'll see thousands of filenames flying by. If you have a slow network connection, this process could take a while. Hang in there, though—you're on your way to building the absolute latest version of Emacs!
除非你得到一个 适合您系统的 Emacs 预构建版本,您需要从源代码构建并安装 Emacs 的许多可执行组件,然后才能使用它。此时,无论你如何获得源代码(HTTP 或 CVS),你只需要编译它即可!以下是帮助您开始执行此任务的一些信息。
Unless you get a prebuilt version of Emacs that is right for your system, you will need to build and install the many executable components of Emacs from source code before you can use it. At this point, it doesn't matter how you got the source code (HTTP or CVS), you just need to compile it! Here is some information to get you started on this task.
您的源代码有一个名为emacs-21.3的顶级目录 。在此目录中,您将找到名为INSTALL和 README的文件。 首先检查README ;它包含有用的一般信息以及最后一刻的发行说明,在继续之前阅读这些信息可能对您很重要。然后阅读INSTALL,其中提供了构建 Emacs 的分步说明。即使您不是 Unix 专家,您也应该能够遵循这些说明。 (为了方便起见,我们提供了一个您可以在本节后面遵循的过程。)
Your source code has a top-level directory with a name like emacs-21.3. In this directory, you will find files called INSTALL and README. Examine README first; it contains useful general information as well as last-minute release notes that may be important for you to read before proceeding. Then read INSTALL, which gives step-by-step instructions for building Emacs. Even if you aren't a Unix expert, you should be able to follow these instructions. (For convenience, we provide a procedure you can follow later in this section.)
FSF 的标准安装程序一直变得更加全面和可靠。尽管如此,构建 Emacs 的实际难易程度主要取决于您所拥有的硬件和软件的组合。 FSF 的安装脚本包括一个名为configure 的程序 ,它会检查您的系统,找出您正在运行的硬件和软件,并相应地配置Emacs。
The FSF's standard installation procedure gets more comprehensive and bulletproof all the time. Still, the actual ease of building Emacs depends primarily on what combination of hardware and software you have. The FSF's installation script includes a program called configure that examines your system, figures out what hardware and software you are running, and configures Emacs accordingly.
如果您有一个流行的组合(例如 Sun SPARC CPU 和最新版本的 Solaris), configure可能会正确猜测。如果这是真的,那么您应该能够构建 Emacs,而无需进行大量调整或技术专业知识。然而,如果您有一个不寻常的设置——非常过时的计算机或操作系统版本、不寻常的硬件/软件组合或非常规的系统配置——那么您将别无选择,只能调整软件。这超出了本书的范围,但是源代码发行版附带的那些 README和INSTALL文件是处理不常见设置时的一个很好的起点。
configure is likely to guess correctly if you have a popular combination (such as a Sun SPARC CPU and a recent release of Solaris). If this is true, you should be able to build Emacs without lots of tweaking or technical expertise. However, if you have an unusual setup—a wildly obsolete computer or operating system version, an unusual hardware/software combination, or unconventional system configuration—then you will have no choice but to tweak the software. That's beyond the scope of this book, but those README and INSTALL files that come with the source distribution are a great place to start when dealing with uncommon setups.
以下是构建 Emacs 的过程,您可以将其用作指南:
Here's a procedure for building Emacs that you can use as a guide:
切换到解压并解压 Emacs 的目录。例如,如果将其放置在 /usr/local/install目录中:
$cd /usr/local/install/emacs-21.3Change to the directory where you uncompressed and unpacked Emacs. For example, if you placed it in the /usr/local/install directory:
$ cd /usr/local/install/emacs-21.3运行配置实用程序。[ 1 ]您应该看到相当多的输出,显示构建脚本正在寻找系统的哪些部分。
$./configure
创建缓存./config.cache
检查主机系统类型... sparc-sun-solaris2.9
检查 gcc...gcc
检查 C 编译器 (gcc) 是否工作...是的
检查 C 编译器 ( gcc ) 是否是交叉编译器...否
检查我们是否正在使用 GNU C...是的
检查 gcc 是否接受 -g... 是
检查 ln -s 是否有效...是的
检查如何运行 C 预处理器... gcc -ERun the configure utility.[1] You should see quite a bit of output that shows what parts of the system the build script is looking for.
$ ./configure
creating cache ./config.cache
checking host system type... sparc-sun-solaris2.9
checking for gcc... gcc
checking whether the C compiler (gcc ) works... yes
checking whether the C compiler (gcc ) is a cross-compiler... no
checking whether we are using GNU C... yes
checking whether gcc accepts -g... yes
checking whether ln -s works... yes
checking how to run the C preprocessor... gcc -E如果配置成功,您应该会看到类似于以下内容的方便的摘要消息:
配置为“sparc-sun-solaris2.9”。
构建过程应该在哪里找到源代码? /usr/local/install/emacs-21.3
Emacs 应使用什么操作系统和机器描述文件?
`s/sol2-5.h' 和 `m/sparc.h'
emacs 应该用什么编译器构建?海湾合作委员会-g-O2
Emacs 应该使用 GNU 版本的 malloc 吗?是的
Emacs 应该使用缓冲区重定位分配器吗?是的
Emacs 应该使用 mmap(2) 进行缓冲区分配吗?不
Emacs 应该使用什么窗口系统? x11
Emacs 应该使用什么工具包?清醒
我们在哪里可以找到 X Windows 头文件?标准目录
我们在哪里可以找到 X Windows 库?标准目录
Emacs 是否使用 -lXaw3d?不
Emacs 使用 -lXpm 吗?是的
Emacs 使用 -ljpeg 吗?不
Emacs 使用 -ltiff 吗?不
Emacs 使用 -lungif 吗?不
Emacs 使用 -lpng 吗?不
Emacs 使用 X 工具包滚动条吗?不如果配置过程因任何原因失败,您需要返回并查阅 安装文档。它针对特定系统和情况提供了一些提示和技巧。
If configure is successful, you should see a handy summary message similar to the following:
Configured for `sparc-sun-solaris2.9'.
Where should the build process find the source code? /usr/local/install/emacs-21.3
What operating system and machine description files should Emacs use?
`s/sol2-5.h' and `m/sparc.h'
What compiler should emacs be built with? gcc -g -O2
Should Emacs use the GNU version of malloc? yes
Should Emacs use a relocating allocator for buffers? yes
Should Emacs use mmap(2) for buffer allocation? no
What window system should Emacs use? x11
What toolkit should Emacs use? LUCID
Where do we find X Windows header files? Standard dirs
Where do we find X Windows libraries? Standard dirs
Does Emacs use -lXaw3d? no
Does Emacs use -lXpm? yes
Does Emacs use -ljpeg? no
Does Emacs use -ltiff? no
Does Emacs use -lungif? no
Does Emacs use -lpng? no
Does Emacs use X toolkit scroll bars? noIf the configuration process fails for any reason, you'll want to go back and consult the INSTALL document. It has several tips and tricks for particular systems and situations.
如果一切都配置正确,您可以继续使用make实用程序编译 Emacs。这可能需要一段时间,所以在出去吃午饭之前就开始吧。
$make
如果 [ ! -f /usr/local/install/emacs-21.3/lisp/abbrev.elc];然后 \
制作引导程序; \
菲
cd lib-src;使所有\
CC='gcc' CFLAGS='-g -O2' CPPFLAGS='' \
LDFLAGS='' MAKE='制作'
gcc -DHAVE_CONFIG_H -I。 -I../src -I/usr/local/install/emacs-21.3/lib-src
-I/usr/local/install/emacs-21.3/lib-src/../src -g -O2 -o test-distrib
/usr/local/install/emacs-21.3/lib-src/test-distrib.c
./test-distrib /usr/local/install/emacs-21.3/lib-src/testfile
gcc -DHAVE_CONFIG_H -I。 -I../src -I/usr/local/install/emacs-21.3/lib-src
-I/usr/local/install/emacs-21.3/lib-src/../src -g -O2 /usr/local/install/
emacs-21.3/lib-src/make-docfile.c -lsocket -lnsl -lkstat -o make-docfile
...If everything is properly configured, you can go ahead and compile Emacs with the make utility. This may take a while, so start it before you head out for lunch.
$ make
if [ ! -f /usr/local/install/emacs-21.3/lisp/abbrev.elc ]; then \
make bootstrap; \
fi
cd lib-src; make all \
CC='gcc' CFLAGS='-g -O2' CPPFLAGS='' \
LDFLAGS='' MAKE='make'
gcc -DHAVE_CONFIG_H -I. -I../src -I/usr/local/install/emacs-21.3/lib-src
-I/usr/local/install/emacs-21.3/lib-src/../src -g -O2 -o test-distrib
/usr/local/install/emacs-21.3/lib-src/test-distrib.c
./test-distrib /usr/local/install/emacs-21.3/lib-src/testfile
gcc -DHAVE_CONFIG_H -I. -I../src -I/usr/local/install/emacs-21.3/lib-src
-I/usr/local/install/emacs-21.3/lib-src/../src -g -O2 /usr/local/install/
emacs-21.3/lib-src/make-docfile.c -lsocket -lnsl -lkstat -o make-docfile
...完成后,安装文档建议使用以下命令测试新构建的 Emacs:
$src/emacs -qEmacs 应该运行,并且您应该看到类似于图 13-2 的介绍屏幕 。
When that completes, the INSTALL document recommends testing your newly built Emacs with the following command:
$ src/emacs -qEmacs should run and you should get an introduction screen similar to Figure 13-2.
如果您看到 Emacs 初始屏幕,[ 2 ] 您状态良好,因此请继续安装它:
$sudo make install或者,如果您想早点root,只需:
$make install系统会提示您输入密码。安装完成后,您就可以使用 Emacs 了。恭喜!
If you see the Emacs splash screen,[2] you're in good shape, so go ahead and install it:
$ sudo make installor, if you su'd to root earlier, simply:
$ make installYou'll be prompted for your password. After the install completes, you should be all set to use Emacs. Congratulations!
正如您可能已经拿起的那样 在阅读本书的其他部分时,我们将 Mac OS X 视为执行许多任务的 Unix 变体。当然,我们这样做是有充分理由的。 Mac OS X 基于 Unix。例如,您可以或多或少地遵循前面部分中的 CVS 和 Unix 构建说明,并完成 Emacs 的完整安装。[ 3 ]然而,如您所知,Mac OS X 在某些方面可能略有不同;默认情况下,它并不具有所有 Unix 实用程序(请参阅有关安装 Ispell 的部分以获取相关示例)。本节介绍在 Mac OS X 上安装 Emacs 以及其他问题,例如从命令行运行 Emacs、更改 Meta 密钥的位置以及安装 Ispell。如果您确实想使用 CVS 从头开始构建 Emacs,我们也有一些相关说明。
As you may have picked up reading other parts of this book, we treat Mac OS X as a Unix variant for many tasks. We do that with good reason, of course. Mac OS X is based on Unix. For example, you could more or less follow the CVS and Unix build instructions in the previous sections and come away with a full installation of Emacs.[3] However, as you know, Mac OS X can be a little different in some ways; it doesn't have all the Unix utilities by default (see the section on installing Ispell for one example of this). This section covers installing Emacs on Mac OS X as well as other issues such as running Emacs from the command line, changing the location of your Meta key, and installing Ispell. And if you do want to build Emacs from scratch using CVS, we have a few notes on that, too.
Mac OS X 自带版本 安装的 Emacs 数量:21.2.1 与 Panther (10.3.2) 和 21.1.1 与 Jaguar (10.2.8)。要启动此版本,请使用“实用程序”文件夹(位于 “应用程序”文件夹内)中的“终端”应用程序 ,然后键入emacs。
Mac OS X comes with a version of Emacs installed: 21.2.1 with Panther (10.3.2) and 21.1.1 with Jaguar (10.2.8). To start this version, use the Terminal application in your Utilities folder (which is inside the Applications folder) and just type emacs.
图 13-3显示了在终端应用程序中运行的内置 Emacs。
Figure 13-3 shows the built-in Emacs running in the Terminal application.
但您应该意识到,虽然它是内置的并且当然是最容易开始使用的,但这个版本的 Emacs 有一些缺点:
But you should be aware that although it is built-in and certainly the easiest to start using, this version of Emacs has a few shortcomings:
它在终端中运行。
It runs, well, you know, in a Terminal.
它没有任何图形用户界面功能,例如图标或预期的鼠标行为。
It does not have any of the graphical user interface features such as icons or expected mouse behavior.
在处理滚动条和某些按键绑定等事务时,终端应用程序通常会取代 Emacs。
The Terminal application often supercedes Emacs when handling things like the scrollbars and some key bindings.
如果您可以忍受这些限制(或者别无选择),那么请随意跳过有关安装 Emacs 的下一部分并继续使用您拥有的版本。本书中的绝大多数信息仍然适用。
If you can live with those restrictions—or have no choice—then feel free to skip the next section on installing Emacs and get on with using the version you have. The vast majority of information in this book still applies.
如果你想要最新的怎么办 版本的 Emacs 但不想自己构建?毕竟,并不是每个 Mac OS X 用户都是老 Unix 黑客! Mac 系统因在一个美观的软件包中提供一些最佳的用户界面约定而闻名。这一点没有改变。如果您不热衷于自行构建应用程序,则可以下载一个漂亮的应用程序包,然后只需拖放即可获得最新版本的 Emacs。
What if you want the latest version of Emacs but don't want to build it yourself? After all, not every Mac OS X user is an old Unix hack! Mac systems made a name for themselves by providing some of the best user interface conventions around in a single, good-looking package. That hasn't changed. If you're not a big fan of do-it-yourself application building, you can download a nifty application bundle and just drag-and-drop your way to a recent build of Emacs.
大多数 Mac 用户都希望获得一个已准备就绪的预构建二进制版本的 Emacs。亚历克斯·赖斯(Alex Rice)就创造了这样的建筑。您可以在线找到它(免费![ 4 ]): http://mindlube.com/products/emacs/index.html。您可以直接从该页面下载,但请务必获取正确的版本。您可以选择 Jaguar (Mac OS X 10.2) 版本或 Panther (Mac OS X 10.3) 版本。
Most Mac users will want to grab a prebuilt binary version of Emacs that's all ready to go. Alex Rice created just such a build. It can be found online (for free![4]) at: http://mindlube.com/products/emacs/index.html. You can download directly from that page, but be sure to grab the correct version. You can pick from the Jaguar (Mac OS X 10.2) version or the Panther (Mac OS X 10.3) version.
您将下载 Mac 磁盘映像格式的.dmg文件。它应该会自动解压并安装,但如果由于某种原因没有自动解压并安装,只需在完全下载后双击.dmg文件即可。
You'll be downloading a .dmg file which is the Mac disk image format. It should automatically unpack and mount itself, but if it doesn't for some reason, just double-click on the .dmg file after it is completely downloaded.
当它启动时,您需要阅读并同意许可证。完成此操作后,您应该安装了一个新的“磁盘”,并且您将看到 Emacs 应用程序已准备好拖放。 (见图13-4。)
As it launches, you'll need to read and agree to the license. After you do that, you should have a new "disk" mounted and you'll see the Emacs application all ready to drag and drop. (See Figure 13-4.)
图 13-4。 Mac OS X (Panther) 上 Emacs 挂载的磁盘映像
Figure 13-4. The mounted disk image for Emacs on Mac OS X (Panther)
将大 gnu 拖到您的应用程序文件夹中即可。这确实就是全部了。非常非常感谢 Alex Rice 和 Mindlube! (将 Emacs 复制到硬盘后,请随意弹出已安装的映像。)
Drag the big gnu to your Applications folder and off you go. That really is all there is to it. Many, many thanks to Alex Rice and Mindlube! (And feel free to eject the mounted image once you have copied Emacs to your hard drive.)
虽然 Mac OS X 是 基于(非常直接)Unix,从构建 21.3.5 开始,构建 Emacs 的最佳选择仍然是采用稍微修改的构建过程。 (Mac 版本应该与版本 21.4 中的正常版本结合在一起。)直到 2004 年,这个单独的过程由 Andrew Choi 维护,并在http://members.shaw.ca/akochoi-emacs/上向公众开放 。幸运的是,尽管 Andrew 不再是 Mac 维护者,但它仍然可用。
While Mac OS X is based (very squarely) on Unix, as of build 21.3.5, your best bet for building Emacs is still to go with a slightly modified build process. (The Mac build should join up with the normal build in version 21.4.) Until 2004, that separate process was maintained by Andrew Choi and made available to the public at http://members.shaw.ca/akochoi-emacs/. Fortunately, it is still available there, although Andrew is no longer the Mac maintainer.
有关构建的完整说明也可以在 Andrew 的网站上找到。虽然构建本质上与其他 Unix 系统相同(运行configure然后make),但最好通过 CVS 检索源代码以获得最新版本。如果您已经安装了 Mac Developer Tools CD,则您将拥有 CVS。如果您尚未安装 Mac 开发工具(通常可在 Mac 或 Mac OS X 附带的单独 CD 上找到),则必须;从源代码构建版本 21.3 需要开发人员工具。
Full instructions on the build can also be found at Andrew's site. While the build is essentially the same as it is for other Unix systems (you run configure and then make), retrieving the source code is best done through CVS to get the latest version. If you have installed the Mac Developer Tools CD, you'll have CVS. If you haven't installed the Mac Developer Tools (usually available on a separate CD that came with your Mac or with your copy of Mac OS X), you must; the Developer Tools are required to build version 21.3 from source.
对于 21.3 版本,Andrew Choi 在http://members.shaw.ca/akochoi-emacs/stories/obtaining-and-building.html上发布了检索和构建 Emacs 所需的步骤。
For the 21.3 build, Andrew Choi has posted the steps required to retrieve and build Emacs at http://members.shaw.ca/akochoi-emacs/stories/obtaining-and-building.html.
如果您计划在 Panther (Mac OS X 10.3) 上采用此方法,只需按照 Andrew 的说明进行操作即可。或者,您可以按照上一节中的 Unix 构建说明进行操作。如果您仍在运行 Jaguar,则需要做一些准备工作。请继续阅读。
If you plan to go this route on Panther (Mac OS X 10.3), just follow Andrew's instructions. Alternatively, you can follow the Unix build instructions from the previous section. If you're still running Jaguar, you'll need to do a bit of preparatory work. Read on.
首先 额外的注意事项是,如果您还没有升级到 Panther (10.3),则应该升级到 Panther (10.3)。严重地。有很多好处。但如果您不适合这样做,那么在安装 Emacs 之前您确实需要绕一些弯路。
The first of the extra notes is that you should upgrade to Panther (10.3) if you aren't there already. Seriously. There are lots of benefits. But if that's just not in the cards for you, you do need to take a small detour before installing Emacs.
Mac OS X 10.2 缺少 Emacs 所需的一个软件:texinfo。 (该工具预装在 10.3 上。)安装并不难;你只需要记住去做即可。您基本上可以像安装任何其他 Unix 软件包一样安装texinfo软件包。您可以回顾上一节以了解更多详细信息,但这里是基础知识。
Mac OS X 10.2 lacks a piece of software required for Emacs: texinfo. (That tool comes preinstalled on 10.3.) It's not hard to install; you just have to remember to do it. You basically install the texinfo package as you would if any other Unix package. You can look back at the previous section for more details, but here are the basics.
您需要从终端应用程序执行这些命令。默认情况下,终端会使用 C-Shell 变体启动您,因此我们将%在本节的命令中使用该字符作为提示符。
You'll need to perform these commands from the
Terminal application. By default,
Terminal starts you out with a C-Shell variant, so
we'll use the % character for the
prompt in the commands for this section.
从 ftp.gnu.org的 /pub/gnu/texinfo文件夹中提取texinfo包。压缩存档文件的名称类似于texinfo-4.7.tar.gz。获取可用的最新版本。
Pull the texinfo package from the /pub/gnu/texinfo folder at ftp.gnu.org. The compressed archive file will be called something like texinfo-4.7.tar.gz. Grab the latest version available.
解压缩存档。
%tar xvzf texinfo-4.7.tar.gz如果您通过浏览器下载了texinfo ,浏览器很可能会为您解压缩它。他们中的一些人甚至可能也打开了它的包装。如果你有一个. tar文件位于桌面上,您可以像这样解压它:
%tar xvf texinfo-4.7.tarUnpack the archive.
% tar xvzf texinfo-4.7.tar.gzIf you downloaded texinfo through a browser, chances are the browser uncompressed it for you. Some of them might even have unpacked it as well. If you have a. tar file sitting on your desktop, you can unpack it like this:
% tar xvf texinfo-4.7.tar移至texinfo-4.7目录并配置您的构建。
%./configureMove to the texinfo-4.7 directory and configure your build.
% ./configure假设一切顺利,您可以构建一切:
%makeAssuming that all goes well, you can build everything:
% make假设一切顺利,您就可以安装它了。但您必须以管理员身份执行此操作。幸运的是,这在终端窗口中很容易做到。只需运行这个命令:
%sudo make installAnd assuming that went well, you can install it. But you'll have to do that as an administrator. Fortunately that's easy to do in the Terminal window. Just run this command:
% sudo make install系统会提示您输入密码。输入它,一切都会顺利。如果您不被允许管理自己的计算机,则您将需要具有管理员权限的人员的帮助。
You'll be prompted for your password. Type it in and everything should go well. If you aren't allowed to administer your own machine, you'll need the help of someone who does have admin privileges.
现在您已经安装了texinfo,您需要下载、解压并安装 Emacs,可以按照 Andrew Choi 的说明或我们在本章前面的“Emacs 和 Unix”部分中的说明进行操作。
Now that you've installed texinfo, you'll need to download, unpack, and install Emacs, either by following Andrew Choi's instructions or ours in the "Emacs and Unix" section earlier in this chapter.
您的 Mac 版本最终应该创建一个可双击的图标,您可以将其拖放到“应用程序” 文件夹中,就像预构建的下载一样。
Your Mac build should end up creating a double-clickable icon that you can drag and drop into your Applications folder just like the prebuilt download.
在 Mac OS X 上,您预装了 Emacs,但是 众所周知,它是 Emacs 的旧版本。假设您已经安装了图形版本并希望使用一些命令行参数启动它。例如,您可能想要运行emacs —debug-init来调试.emacs文件。 Mac OS X Gnu 图标当然应该永久固定在您的 Dock 上,但有时命令行也是正确的选择。
On Mac OS X, you have Emacs preinstalled, but as we know, it is an older version of Emacs. Let's say that you have installed the graphical version and want to start it with some command-line arguments. For example, you might want to run emacs —debug-init to debug your .emacs file. The Mac OS X Gnu icon certainly should be a permanent fixture on your Dock, but at times the command line is the way to go.
我们从 Andrew Choi 的 Mac OS X 常见问题解答中学到了这个技巧,为了方便起见,我们稍微调整了一下,在这里分享它。查看他的页面:http://members.shaw.ca/akochoi-emacs/stories/faq.html。
We learned this trick from Andrew Choi's Mac OS X FAQ, and we share it here, slightly tweaked, for convenience. Check out his page at http://members.shaw.ca/akochoi-emacs/stories/faq.html.
本质上,您可以将 Mac OS X 附带的二进制文件替换为运行您安装的新版本 Emacs 的 shell 脚本。您可能只想重命名旧的二进制文件,以便有时可以使用它。
Essentially, you replace the binary that comes with Mac OS X with a shell script that runs the new version of Emacs you installed. You might want to simply rename the old binary so that you can on occasion use it instead.
程序如下。
Here's the procedure.
要确定在您键入emacs时运行哪个 Emacs ,请在终端应用程序中键入which emacs 。
% which emacs
/usr/bin/emacsTo be sure which Emacs runs when you type emacs, type which emacs in the Terminal application.
% which emacs
/usr/bin/emacs重命名或删除/usr/bin/emacs。
%sudo mv /usr/bin/emacs /usr/bin/oldemacsRename or delete /usr/bin/emacs.
% sudo mv /usr/bin/emacs /usr/bin/oldemacs系统会提示您输入密码。
You'll be prompted for your password.
使用以下两行创建一个名为emacs的文件:
#!/bin/sh /Applications/Emacs.app/Contents/MacOS/Emacs "$@"
如果您将 Emacs 安装到不同的文件夹中,请相应地调整第二行。
Create a file called emacs with the following two lines:
#!/bin/sh /Applications/Emacs.app/Contents/MacOS/Emacs "$@"
If you installed Emacs into a different folder, adjust the second line accordingly.
将您创建的文件移动到/usr/bin:
%sudo mv emacs /usr/binMove the file you created to /usr/bin:
% sudo mv emacs /usr/bin将/usr/bin/emacs更改为可由全世界执行:
%chmod +x /usr/bin/emacs现在,您只需在终端窗口中键入 emacs 即可调用图形化Emacs,无论是否带有命令行参数。[ 5 ]
Change /usr/bin/emacs to be executable by the world:
% chmod +x /usr/bin/emacsNow you can invoke graphical Emacs from the terminal window simply by typing emacs, with or without command-line arguments.[5]
这本书里提到过 在 Mac OS X 上使用 Meta的Command键。默认情况下, Command键(有时称为Open Apple键,或更简单地称为 xxxMacSymxxx)是Meta。但事实上你有选择。变量mac-command-key-is-meta可用于选择要使用的键。
This book has mentioned using the Command key for Meta on Mac OS X. By default, the Command key (sometimes called the Open Apple key, or more simply xxxMacSymxxx) is Meta. But in fact you have a choice. The variable mac-command-key-is-meta can be used to select which key you want to use.
顾名思义,将mac-command-key-is-meta设置为t表示您使用 xxxMacSymxxx 作为Meta键。因此,您可以将 Mx组合键入 xxxMacSymxxx x。
As the variable name implies, setting mac-command-key-is-meta to t means that you use xxxMacSymxxx as the Meta key. So you can type the M-x combination as xxxMacSymxxxx.
另一种方法(将mac-command-key-is-meta设置为nil)将Option(或Alt)键设置为您的Meta键。如果您想继续使用Command键来执行 Mac 功能,或者您发现Option更容易访问,则可以执行此操作。当然,事情并不那么简单。 Emacs 仍然捕获 Command键。这种陷阱应该用另一个变量来关闭:mac-pass-command-to-system,但说实话,我们从来没有让它发挥作用。
The alternative (setting mac-command-key-is-meta to nil) sets the Option (or Alt) key to be your Meta key. You might do this if you want to continue using the Command key for Mac functions or if you find that Option is simply easier to reach. Of course, it's not quite that simple. Emacs still traps the Command key. That trapping is supposed to be turned off with one more variable: mac-pass-command-to-system, but to be honest, we never got that to work.
正如第 3 章中提到的,Emacs 使用 Ispell 的拼写检查功能。然而,尽管有大量的钩子,Ispell 可执行文件并不是 Emacs 的一部分,并且默认情况下不会安装在 Mac OS X 上。因此,您必须安装 Ispell 才能使拼写检查正常工作。
As mentioned in Chapter 3, Emacs uses Ispell for its spell-checking functionality. However, despite voluminous hooks to it, the Ispell executable is not part of Emacs and is not installed by default on Mac OS X. You must therefore install Ispell to get spell-checking to work properly.
我们采取了简单的方法来做到这一点:下载并安装 Fink(有关说明,请参阅http://fink.sourceforge.net )。 Fink 是一款通用的 Mac OS X 安装程序,可让您轻松在 Mac 上安装 Unix 软件。
We took the easy path to doing this: downloading and installing Fink (see http://fink.sourceforge.net for instructions). Fink is an all-purpose Mac OS X installer that enables you to install Unix software on your Mac easily.
安装 Fink 后,安装 Ispell 就完全轻松了:
After installing Fink, installing Ispell was completely painless:
%fink install ispell % fink install ispell只需要执行进一步的步骤,Emacs 就能无需调整即可找到 Ispell。在 Fink 安装 Ispell 的位置 ( /sw/bin/ispell ) 和 Emacs 期望 Ispell 所在的位置 ( /usr/bin/ispell ) 之间创建一个符号链接。[ 6 ]
Just one further step is required so that Emacs finds Ispell without tweaking. Create a symbolic link between the location where Fink installs Ispell (/sw/bin/ispell) and where Emacs expects Ispell to be (/usr/bin/ispell).[6]
%sudo ln -s /sw/bin/ispell /usr/bin/ispell% sudo ln -s /sw/bin/ispell /usr/bin/ispell瞧。现在使用 Ispell 进行 Emacs 拼写检查的工作方式如第 3 章中所述。
Voilà. Emacs spell-checking with Ispell now works as described in Chapter 3.
[ 3 ]我们说“或多或少”是因为在我们付印时,您仍然需要从单独的站点获取源代码。这种差异最终也应该消失。
[3] We say "more or less" because at the time we went to press, you still needed to grab the source from a separate site. That difference should eventually disappear as well.
[ 4 ]捐赠以支付托管费用当然将不胜感激;该网站包含一个贡献链接。
[4] A donation to defray hosting costs would certainly be appreciated; the site includes a link for contributions.
[ 5 ]您仍然可以使用-nw命令行参数(输入emacs -nw)将这个新的 Emacs 作为普通终端应用程序运行。
[5] You can still run this new Emacs as a plain Terminal app with the -nw command-line argument (type emacs -nw.)
[ 6 ]我们在 John Schneider 的网页上找到了这个提示,名为“让 Mac OS X.3 的行为几乎像我的 Linux 盒子”( http://www.eecs.wsu.edu/~schneidj/mac-os-x- 10.3.html)。
[6] We found this hint on John Schneider's web page called "Getting Mac OS X.3 to Behave Almost Like My Linux Boxes" (http://www.eecs.wsu.edu/~schneidj/mac-os-x-10.3.html).
您还可以下载并安装适用于各种 Windows 平台(Win95、Win98、Win2K、WinXP 等)的 Emacs 21.3。由于大多数 Windows 计算机不附带从头开始构建 Emacs 所需的工具,因此我们将考虑下载和安装预构建的可执行文件。[ 7 ]
You can also download and install Emacs 21.3 for the various Windows platforms (Win95, Win98, Win2K, WinXP, and so on). As most Windows machines do not ship with the tools required to build Emacs from scratch, we'll look at downloading and installing prebuilt executables.[7]
与所有平台一样,您 在 Windows 上安装 Emacs 时有选择。您可以安装由 FSF 托管的二进制文件(可能较旧,但肯定稳定)。您可以在线找到更新的二进制文件(我们会向您指出我们喜欢的那个)。您还可以从 CVS 构建 Emacs,但如果您在 Windows 上这样做,您很可能不会阅读本书。 Windows 没有默认编译器。
As with all platforms, you have choices when installing Emacs on Windows. You can install a binary hosted by the FSF (likely to be older, but certainly stable). You can find a more recent binary online (we'll point you to the one we prefer). You could also build Emacs from CVS, but if you're doing that on Windows, chances are you are not reading this book. Windows comes with no default compilers.
我们最新二进制文件的来源是 Nqmacs(http://sourceforge.net/projects/nqmacs/)。这只是来自 CVS 源的最新版本的 GNU Emacs 的构建,而不是顾名思义的单独版本的 Emacs。 Windows 二进制文件定期在此发布,使 Windows 用户无需自行构建即可访问最新版本。
Our source for the latest binaries is Nqmacs (http://sourceforge.net/projects/nqmacs/). This is simply a build of the latest version of GNU Emacs from CVS sources, not a separate version of Emacs as the name may imply. Windows binaries are posted here on a regular basis, giving Windows users access to the latest version without having to build it themselves.
要在 Windows 上安装,只需下载最新的二进制文件,使用 WinZip 或 Windows 自己的解压实用程序解压到新文件夹中,转到bin 子文件夹并双击runemacs.exe。通过右键单击该图标,您可以将该图标的副本发送到桌面。
To install on Windows, simply download the latest binaries, unpack into a new folder using WinZip or Windows own decompression utilities, go to the bin subfolder and double-click on runemacs.exe. By right-clicking on the icon, you can send a copy of the icon to the desktop.
正如我们提到的,二进制文件 FSF 的成员稳定,但普遍年龄较大。例如,在撰写本文时,Nqmacs 站点提供 2004 年 7 月 25 日构建的二进制文件,而 FSF 站点提供 2004 年 3 月 10 日构建的二进制文件。
As we mentioned, the binaries at the FSF are stable but generally older. For example, at this writing, the Nqmacs site provides binaries built on 7/25/04 while the FSF's site provides binaries from 3/10/2004.
要从 FSF 下载 Emacs,只需将浏览器指向 http://ftp.gnu.org/pub/gnu/emacs/。向下滚动找到windows文件夹。在那里,您应该可以找到几个下载内容。二进制文件具有三种类型:
To download Emacs from the FSF, simply point your browser at http://ftp.gnu.org/pub/gnu/emacs/. Scroll down to find the windows folder. In there, you should find several downloads. The binaries come in three flavors:
bare (barebin)——你开始工作所需的最低限度
bare (barebin)—the bare minimum you need to get going
标准(bin)——大多数人运行时需要的
standard (bin)—what most folks need to get running
full (fullbin)——全餐交易;一切,然后一些
full (fullbin)—the full meal deal; everything and then some
抓住你想要的并下载它。您可以使用 WinZip ( http://www.winzip.com ) 来解压它。如果您安装了 Cygwin 实用程序,您还可以使用 gunzip和tar,正如我们在 Unix 安装部分中讨论的那样。
Grab the one you want and download it. You can use WinZip (http://www.winzip.com) to unpack it. If you have the Cygwin utilities installed, you can also use gunzip and tar as we discussed in the Unix installation section.
当心!README.W32文件指出,如果将 Emacs 发行版解压到一个或多个目录名包含空格的路径,则可能会遇到一些小问题。例如,不要将 Emacs 解压到Program Files目录中。如果您不喜欢直接将内容添加到 C: 驱动器,请创建一个“Applications”文件夹或类似的文件夹,然后在该文件夹中解压 Emacs。
Be careful! The README.W32 file notes that you may run into some small problems if you unpack your Emacs distribution into a path where one or more of the directory names contains spaces. For example, don't unpack Emacs in the Program Files directory. If you don't like adding things directly to your C: drive, create an Applications folder or something similar and unpack Emacs in that folder.
打开包装后,您就完成了 99% 的工作。实际上,最新版本的 Emacs 不需要任何其他东西;您只需双击runemacs.exe (位于 Emacs 文件夹的 bin 目录中)即可开始!如果您愿意,可以在“开始”菜单或桌面上创建快捷方式。只需将它们指向runemacs.exe即可完成设置。
After that's unpacked, you're 99 percent of the way there. The latest versions of Emacs need nothing else, actually; you just double-click on runemacs.exe (in the bin directory of your Emacs folder) and off you go! If you like, you can create shortcuts in your Start menu or on the desktop. Just point them at runemacs.exe and you should be set.
可能是最大的 Windows需要考虑的是.emacs文件的位置。该文件位于您的“主”目录中。我们在那里使用引号是因为 Windows 世界不像 Unix 和 Mac OS X 等其他操作系统那样有严格定义的主目录。默认情况下,Emacs 假定 C:\文件夹是您的主目录。您可以将.emacs文件放在那里,但您也可以使用名为 HOME 的 Windows 环境变量修改您的主目录。要在 Windows XP 上更改此环境变量,请从控制面板中选择系统。将显示“系统属性”窗口。选择“高级”选项卡,然后选择“环境变量”。 HOME 可能未列出;单击“新建”,然后键入 HOME 和所需主目录的路径。 Emacs 现在将在此目录中查找 .emacs文件。
Probably the single biggest Windows consideration is the location of the .emacs file. This file goes in your "home" directory. We use quotes there because the Windows world doesn't have a strictly defined home directory the way some other operating systems like Unix and Mac OS X do. By default, Emacs assumes that the C:\ folder is your home directory. You can put your .emacs file there, but you can also modify your home directory using the Windows environment variable called HOME. To change this environment variable on Windows XP, select System from the Control Panel. A System Properties window displays. Choose the Advanced tab, then choose Environment Variables. HOME is probably not listed; click on New, then type HOME and the path to your desired home directory. Emacs will now look for the .emacs file in this directory.
由于命名兼容性问题,旧版 Windows 版本的 Emacs 使用_emacs文件而不是 .emacs文件进行自定义和配置。该文件仍然是一个有效的选项。但是,如果 在主目录中同时找到_emacs和.emacs ,则仅使用.emacs 。
Because of naming compatibility issues, older Windows versions of Emacs used the _emacs file rather than the .emacs file for customization and configuration. This file is still a valid option. However, if both _emacs and .emacs are found in the home directory, only .emacs is used.
Emacs bin文件夹包含两个相关的 文件,每个文件都有一个 Gnu 图标:emacs.exe和 runemacs.exe。通常您会使用runemacs.exe;这会以图形方式运行 Emacs,而无需打开控制台窗口。另一个文件 emacs.exe可用于从命令行运行 Emacs,如下所述。
The Emacs bin folder includes two related files, each sporting a Gnu icon: emacs.exe and runemacs.exe. Typically you'll use runemacs.exe; this runs Emacs graphically without opening a console window. The other file, emacs.exe, can be used to run Emacs from the command line as described next.
要从命令行运行 Emacs,请 cd到安装 Emacs 的目录并输入emacs -nw(或您想要使用的任何命令行参数;-nw在控制台窗口中运行 Emacs)。您还可以通过选择“开始” → “运行”,然后选择“浏览”来找到emacs.exe来执行此操作。添加您想要的任何命令行参数,然后单击“确定”以使用这些参数调用 Emacs。
To run Emacs from the command line, cd to the directory where you installed Emacs and type emacs -nw (or whatever command-line argument you wanted to use; -nw runs Emacs in the console window). You can also do this by choosing Start→ Run, then selecting Browse to locate emacs.exe. Add any command-line arguments you wish, and then click OK to invoke Emacs using these arguments.
CUA代表通用 用户访问,最初由 IBM 开发的标准。 CUA 要求某些按键应始终执行某些功能。例如,在 Windows 中,抄送和抄送从一个应用程序复制并粘贴到另一个应用程序。如您所知,Emacs 将这些键绑定用于其自身目的。
CUA stands for common user access, a standard originally developed by IBM. CUA mandates that certain keys should always perform certain functions. In Windows, for example, C-c copies and C-v pastes from one application to another. As you know, Emacs uses these key bindings for its own purposes.
这就是 Kim Storm 的 CUA 模式的用武之地。该模式非常流行,现在已成为 Emacs 的一部分。[ 8 ]它允许标准 Windows 键绑定(例如用于剪切的Cx和 用于粘贴的Cv)在 Emacs 中正常工作。这非常聪明——这些键仅在存在活动选择时才进行剪切和粘贴。这使得Cc Cf等多笔划命令的正常功能保持良好状态。
That's where Kim Storm's CUA mode comes in. This mode was so popular that it is now part of Emacs.[8] It allows standard Windows key bindings, like C-x for cut and C-v for paste, to work properly within Emacs. It's quite clever—these keys cut and paste only when an active selection exists. That leaves the normal functionality of multistroke commands like C-c C-f in fine shape.
要打开 CUA 模式,请从选项菜单中选择 Cx/Cc/Cv 剪切粘贴 (CUA)。如果您决定要对多个会话使用 CUA 模式,请选择“保存选项”以使“自定义”(在第 10 章中讨论)自动将其添加到您的 .emacs文件中。
To turn on CUA mode, select C-x/C-c/C-v cut-and-paste (CUA) from the Options menu. If you decide you want to use CUA mode for multiple sessions, select Save Options to have Custom (discussed in Chapter 10) automatically add it to your .emacs file.
从选项名称可以看出,该模式下,Cx用于剪切文本,Cc用于复制文本,Cv用于粘贴文本。不太明显的是Cz运行撤消而不是最小化窗口(在 CUA 模式下,您可以使用Cx Cz最小化)。
As you can see from the option name, in this mode, C-x is used for cutting text, C-c is used for copying text, and C-v is used for pasting text. What is not so apparent is that C-z runs undo rather than minimizing the window (in CUA mode, you can minimize using C-x C-z).
如果您习惯于在使用Cx Cx剪切区域之前确认区域怎么办?在这种情况下,您可以键入Cc Cx Cx 。这在一定程度上是有效的,因为Cc取消了活动区域。请记住,Cx 通常会削减。
What if you're used to confirming a region before you cut it using C-x C-x? You can type C-c C-x C-x in this case. This works in part because C-c cancels the active region. Remember that C-x would normally cut.
严格来说,如果您输入的速度足够快, Cx Cx 不会立即剪切文本。 Cut 实际上与Cx <timeout>绑定。换句话说,Emacs 会观察您是否很快输入其他内容。如果您有一个突出显示的区域并输入Cx Cs来保存缓冲区,Emacs 会做正确的事情。但如果您在 Cx之后暂停,则会剪切文本。对于Cc来说也是如此。如果您在Cc之后立即键入另一个序列,Emacs 将使用Cc作为前缀。如果您暂停,它会复制突出显示的文本。
Strictly speaking, C-x C-x doesn't immediately cut text, if you type it fast enough. Cut is really bound to C-x <timeout>. In other words, Emacs is watching to see if you type something else really quickly. If you have a region highlighted and type C-x C-s to save the buffer, Emacs does the right thing. But if you pause after C-x, you'll cut text. This is true of C-c as well. If you immediately type another sequence after C-c, Emacs uses C-c as a prefix. If you pause, it copies the highlighted text.
CUA 模式还有一些其他有趣的行为。它具有非常先进的矩形支持。 (矩形编辑在第 7 章中描述。)它还有替换突出显示文本的常见行为。如果您选择一个区域并开始输入,突出显示的文本将被替换。更进一步,您可以通过这种方式进行快速而肮脏的搜索和替换。假设您键入的文本只是您要替换文本的多个相同实例中的第一个。键入Mv(对于cua-repeat-replace-region)将替换下一个实例。重复此命令以继续进行替换。如果没有要替换的字符串,Mv 将不执行任何操作。
CUA mode has a few other interesting behaviors. It has highly advanced rectangle support. (Rectangle editing is described in Chapter 7.) It also has the common behavior of replacing highlighted text. If you select a region and start typing, the highlighted text is replaced. Taking this one step further, you can do a quick and dirty search and replace in this way. Let's say that the text you typed over is just the first of several identical instances where you want to replace text. Typing M-v (for cua-repeat-replace-region) replaces the next instance. Repeat this command to continue making replacements. If there is no string to replace, M-v does nothing.
例如,让我们以经典的狄更斯段落为例,用 rhymes替换单词times:
For example, let's take our classic Dickens passage and replace the word times with rhymes:
您可能喜欢 CUA 模式,也可能讨厌它;查看您的手指是否准备好执行此选项的唯一方法就是尝试一下。如果您使用 Emacs 多年,您可能会发现 CUA 模式不断执行意想不到的操作。您的手指习惯已按照 Emacs 的方式进行设置。另一方面,很难在应用程序之间来回移动并始终改变您的手指习惯。如果您尚未习惯 Emacs 键绑定,您可能会像许多人一样喜欢 CUA 模式。
You may love CUA mode or you may hate it; the only way to see if your fingers are ready for this option is to try it out. If you've used Emacs for years, you may find CUA mode keeps doing unexpected things. Your finger habits are set to Emacs's ways. On the other hand, it's hard to move back and forth between applications and change your finger habits all the time. If you have not yet gotten used to the Emacs key bindings, you may well love CUA mode, as many people do.
表13-1列出了CUA模式 命令。
Table 13-1 lists CUA mode commands.
表 13-1。 CUA模式命令
Table 13-1. CUA mode commands
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
抄送 CX CX C-c C-x C-x |
cua 交换点和标记 cua-exchange-point-and-mark |
交换光标和标记的位置。 Exchange location of cursor and mark. |
|
抄送 C-c |
复制区域作为终止 copy-region-as-kill |
复制区域。 Copy the region. |
|
Cx 或 C-w 或 S-删除 C-x or C-w or S-Delete |
杀伤区 kill-region |
删除区域。 Delete the region. |
|
Cv 或 C-y 或 S-插入 C-v or C-y or S-Insert |
铜浆糊 cua-paste |
粘贴最近删除或复制的文本。 Paste most recently killed or copied text. |
|
MV M-v |
cua 重复替换区域 cua-repeat-replace-region |
突出显示并替换一个字符串后,找到下一个字符串并以相同的方式替换它。 After highlighting and replacing a string, find the next string and replace it the same way. |
|
上一页 PgUp |
cua 向上滚动 cua-scroll-up |
向上滚动一页(或滚动到缓冲区的开头)。 Scroll up one page (or to the beginning of the buffer). |
|
下页 PgDown |
cua-向下滚动 cua-scroll-down |
向下滚动一页(或滚动到缓冲区末尾)。 Scroll down one page (or to the end of the buffer). |
|
我的 M-y |
cua-paste-pop cua-paste-pop |
在Cv之后,粘贴先前删除的内容。 After C-v, pastes earlier deletion. |
|
Cz 或 C-x u C-z or C-x u |
取消撤销 cua-undo |
撤消最后一次更改。 Undoes the last change. |
|
CxCz C-x C-z |
图标化框架 iconify-frame |
最小化当前帧(Cz 在 CUA 模式之外执行的操作)。 Minimize the current frame (what C-z does outside CUA mode). |
在 Windows 上安装 Ispell 可以 很棘手。 Emacs 20 及更高版本包含 Flyspell 等功能,而早期版本的 Ispell 无法处理该功能。许多 Windows 用户不会编译自己的软件,即使编译了,最新的 Ispell 也无法与 Emacs 一起使用。
Installing Ispell on Windows can be tricky. Emacs 20 and beyond includes features like Flyspell and earlier versions of Ispell won't handle that functionality. Many Windows users do not compile their own software, and even if they did, the very newest Ispell also doesn't work with Emacs.
我们在 Raymond Zeitler 的一篇文章 ( http://lists.nongnu.org/archive/html/help-emacs-windows/2004-06/msg00023.html )中找到了我们在此描述的版本,我们衷心感谢他。这个版本的唯一缺点是它是为英语使用者设计的。它可能很好地适用于其他语言,但您必须找到 适合您的语言的<language>.hash文件。
We found the version we describe here in a post by Raymond Zeitler (http://lists.nongnu.org/archive/html/help-emacs-windows/2004-06/msg00023.html), and we thank him heartily for it. The only downside to this version is that it is designed for English speakers. It may well work with other languages, but you'd have to find the <language>.hash file appropriate for your language.
第一步是下载 Ispell 3.1.20 的 Windows 二进制文件。[ 9 ]
The first step is to download a Windows binary of Ispell 3.1.20.[9]
打开命令窗口。在 Windows XP 上,您可以使用“开始” → “运行”打开它,然后输入命令 并单击“确定”。
Open a command window. On Windows XP, you open it using Start → Run, then typing command and clicking OK.
创建一个临时目录并移动到那里(您可以用另一个名称替换tmp)。
Create a temporary directory and move there (you can substitute another name for tmp).
C:\>mkdir tmpC:\>cd tmp
C:\>mkdir tmpC:\>cd tmp
通过 FTP 传输至gatewaykeeper.dec.com。
FTP to gatekeeper.dec.com.
C:\tmp>ftp gatekeeper.dec.comC:\tmp> ftp gatekeeper.dec.com输入匿名作为您的用户名,输入您的电子邮件地址作为密码。
Type anonymous as your username and your email address as your password.
移动到/pub/GNU/windows/emacs/contrib 目录。
Move to the /pub/GNU/windows/emacs/contrib directory.
C:\tmp>cd /pub/GNU/windows/emacs/contribC:\tmp> cd /pub/GNU/windows/emacs/contrib键入bin以更改为二进制模式。
Type bin to change to binary mode.
C:\tmp>binC:\tmp> bin下载ispell.zip。
Download ispell.zip.
C:\tmp>get ispell.zipC:\tmp> get ispell.zip输入bye关闭 ftp 会话,然后输入 exit关闭 MS-DOS 窗口。
Type bye to close your ftp session, then exit to close the MS-DOS window.
使用 WinZip 或 Windows 自带的解压缩实用程序解压缩存档。我们需要移动一些文件以使 Ispell 在 Emacs 中正常工作。
Unzip the archive with WinZip or Windows' own decompression utility. We need to move a few files around to make Ispell work properly with Emacs.
将ispell.exe移动到 Emacs 的 bin文件夹中。例如,如果您将安装 Emacs 的文件夹称为nqmacs,则可以将该文件放置在nqmacs\bin中。
Move ispell.exe to Emacs' bin folder. For example, if you called the folder where you installed Emacs nqmacs, you would place the file in nqmacs\bin.
将english.hash移至您的主目录( C : 或您之前定义为.emacs文件位置的目录)。现在将 english.hash复制到 american.hash(这两个文件都必须存在,Ispell 才能正常工作)。我们怀疑但无法证实这对于需要英式英语词典的系统用户来说是不必要的。
Move english.hash to your home directory (either C: or the one you defined earlier as the location for your .emacs file). Now copy english.hash to american.hash (both files must exist for Ispell to work properly). We suspect but cannot verify that this would not be necessary for users of systems expecting British English dictionaries.
Windows 中的 Emacs 世界还有更多功能。我们鼓励您查看常见问题和文档在线提供:http://www.gnu.org/software/emacs/windows/。
There's a lot more to the world of Emacs in Windows. We encourage you to check out the frequently asked questions and documentation available online at http://www.gnu.org/software/emacs/windows/.
[ 7 ]好吧好吧。如果您想在 Windows 上构建它,您当然可以。我们建议从 Cygwin 项目 ( http://www.cygwin.com )获取各种开发工具,例如make 和gcc,然后遵循 Unix 构建说明。
[7] Okay, okay. If you want to build it on Windows, you certainly can. We suggest grabbing the various development tools like make and gcc from the Cygwin project (http://www.cygwin.com) and then following the Unix build instructions.
[ 8 ]如果您运行的是旧版本的 Emacs 并需要此功能,请访问http://www.cua.dk/emacs.html下载并安装 CUA 模式。
[8] If you are running an older version of Emacs and want this functionality, visit http://www.cua.dk/emacs.html to download and install CUA mode.
[ 9 ]该二进制文件也可以从本书的网站http://www.oreilly.com/catalog/gnu3获得。
[9] This binary is also available from this book's web site, http://www.oreilly.com/catalog/gnu3.
Emacs 拥有所有文本编辑器中最全面的帮助工具,并且是所有程序中最好的此类工具之一。事实上,Emacs 帮助工具可能将我们编写本书所花费的时间缩短一个数量级,并且它们可以在您不断寻求更多有关 Emacs 的过程中为您提供不可估量的帮助。
Emacs has the most comprehensive help facility of any text editor—and one of the best such facilities of any program at all. In fact, the Emacs help facilities probably cut down the time it took for us to write this book by an order of magnitude, and they can help you immeasurably in your ongoing quest to learn more about Emacs.
在本章中,我们从以下几个方面描述 Emacs 帮助:
In this chapter, we describe Emacs help in the following areas:
教程。
The tutorial.
帮助键 ( Ch ) 和帮助菜单,可让您获得有关各种主题的帮助。
The help key (C-h) and Help menu, which allow you to get help on a wide variety of topics.
复杂命令的帮助工具,如query-replace和dired。
The help facilities of complex commands like query-replace and dired.
浏览 Emacs 手册并使用信息文档阅读器。
Navigating Emacs manuals and using the info documentation reader.
完成,Emacs 帮助您完成函数名称、变量、文件名等的输入。完成不仅可以节省您的时间并帮助您完成您所知道的函数名称,还可以帮助您发现新的命令和变量。
Completion, in which Emacs helps you finish typing names of functions, variables, filenames, and more. Completion not only saves you time and helps you complete names of functions you know about but can help you discover new commands and variables.
如果你刚刚开始 使用 Emacs,通过输入Ch t(获取 help-with-tutorial )来查看教程,这会删除所有多余的窗口(只留下一个)并启动边做边学的教程。实际上,它在窗口中显示一个名为 TUTORIAL的文件。该教程目前有 21 种语言版本。本教程介绍了以下 Emacs 功能:
If you are just starting out with Emacs, check out the tutorial by typing C-h t (for help-with-tutorial), which deletes all extra windows (leaving just one) and starts up a learn-by-doing tutorial. Actually, it displays a file called TUTORIAL in the window. The tutorial is currently available in 21 languages. The tutorial provides an introduction to the following Emacs features:
基本光标运动
Basic cursor motion
删除并拉出
Delete and yank
访问和保存文件
Visiting and saving files
缓冲器
Buffers
文本和自动填充模式
Text and auto-fill modes
增量搜索
Incremental search
基本帮助命令
Basic help commands
您可能希望将本教程与第 1 章和第 2 章一起使用。该教程很有帮助,但它必然只涵盖最基本的信息。
You might want to use the tutorial along with Chapter 1 and Chapter 2. The tutorial is helpful, but of necessity it covers only the most basic information.
Emacs 有很多帮助
命令,这些命令可作为标准 Emacs 命令或
Ch帮助键的选项。它们可用于查找有关命令、击键、变量、模式以及有关 Emacs 的各种一般信息的信息。最基本的帮助命令是
Ch Ch ( help-for-help )。奇?还调用help-for-help。该命令使 Emacs*Help*在窗口中打开一个缓冲区,其中包含所有帮助命令的描述。您可以键入这些帮助键中的任何一个,或者,如果您按Space,
*Help*窗口会向下滚动,就像您按
Cv一样。任何其他键都会中止整个过程。如果滚动到帮助文档的底部,您可以键入帮助键或任何其他键来中止。
Emacs has many help
commands,
which are available as standard Emacs commands or as options to the
C-h help key. They can be used to
find information about commands, keystrokes, variables, modes, and
various things about Emacs in general. The most basic help command is
C-h C-h (help-for-help). C-h
? also invokes help-for-help. This command causes Emacs to
open a *Help* buffer in a window with descriptions
of all the help commands. You can type any one of these help keys,
or, if you press Space, the
*Help* window scrolls down as if you pressed
C-v. Any other key aborts the whole
process. If you scroll to the bottom of the help documentation, you
can type a help key or any other key to abort.
中列出的键*Help*是那些附加到帮助键后可随时运行 Emacs 帮助命令的键。帮助命令分为两大类:提供特定问题答案的命令和提供有关 Emacs 的一般信息的命令。
The keys listed in the *Help* are those that, when
appended to your help key, run Emacs help commands at any time. Help
commands fall into two general categories: those that provide answers
to specific questions and those that give general information about
Emacs.
当您熟悉 Emacs 后,您会发现前一类中的帮助命令非常有用。由于它太大且功能丰富,有时您需要查找诸如按键或命令名称之类的详细信息,或者当您需要使用 Emacs 执行某些操作但您不知道具体该怎么做时。正如我们在本书中一再重复的那样,Emacs 可能会满足您的需求;你只需要弄清楚如何做。帮助命令可以让您立即找到这些内容,而无需离开 Emacs,也无需成为参考手册(甚至本书)的奴隶。
You will find the help commands in the former category to be invaluable after you have become comfortable with Emacs. Because it is so large and functionally rich, there will be times when you need to look up a detail such as a keystroke or command name or when you need to do something with Emacs that you don't know exactly how to do. As we've repeated again and again throughout this book, Emacs probably does what you want; you just need to figure out how. The help commands let you find these things out immediately, without leaving Emacs and without being a slave to your reference manual (or even this book).
让我们从帮助命令开始 当您需要查找特定详细信息时,这很有用。您可能最常使用表 14-1中列出的命令。
Let's start with the help commands that are useful when you need to look up a specific detail. You'll probably use the commands listed in Table 14-1 most often.
表 14-1。详细信息帮助命令
Table 14-1. Detail information help commands
|
击键 Keystrokes |
命令名称 Command name |
问题已回答 Question answered |
|---|---|---|
|
氯 C-h c |
简要描述关键 describe-key-briefly |
这个击键序列运行什么命令? What command does this keystroke sequence run? |
|
Ch k 帮助 → 描述 → 描述键 C-h k Help → Describe → Describe Key |
描述键 describe-key |
这个击键序列运行什么命令,它有什么作用? What command does this keystroke sequence run, and what does it do? |
|
Ch f 帮助 → 描述 → 描述功能 C-h f Help → Describe → Describe Function |
描述功能 describe-function |
这个函数有什么作用? What does this function do? |
|
Ch v 帮助 → 描述 → 描述变量 C-h v Help → Describe → Describe Variable |
描述变量 describe-variable |
这个变量是什么意思,它的值是多少? What does this variable mean, and what is its value? |
|
Ch m 帮助 → 描述 → 描述缓冲模式 C-h m Help → Describe → Describe Buffer Modes |
描述模式 describe-mode |
告诉我当前缓冲区所处的模式。 Tell me about the modes the current buffer is in. |
|
Ch b 帮助 → 描述 → 列出按键绑定 C-h b Help → Describe → List Key Bindings |
描述绑定 describe-bindings |
该缓冲区的所有键绑定是什么? What are all the key bindings for this buffer? |
|
chw C-h w |
哪里 where-is |
该命令的键绑定是什么? What is the key binding for this command? |
|
CH C-h s |
描述语法 describe-syntax |
该缓冲区的语法表是什么? What is the syntax table for this buffer? |
|
叶绿素 C-h l |
视野损失 view-lossage |
我输入的最后 100 个字符是什么? What are the last 100 characters I typed? |
|
车 C-h e |
查看回声区域消息 view-echo-area-messages |
在此会话期间,迷你缓冲区中出现了哪些消息? What messages have appeared in the minibuffer during this session? |
如果您按错了键,并且您的缓冲区发生了某些情况,但您不确定会发生什么情况,该怎么办?通常,最安全的做法是按C-_
或Cx u(撤消)。但有时这个命令不会有帮助,例如,失控的替换字符串。如果您还记得输入的内容,则可以使用Ch c(用于
描述密钥简短)来查看运行了什么命令;只需在提示符处重新键入有问题的击键,Emacs 就会以绑定到迷你缓冲区中的键的命令名称进行响应。如果仅命令名称没有帮助,Ch k
(用于描述键)会弹出一个
*Help*窗口,其中包含命令的描述及其名称和键绑定。 (Ch k和Ch c还可以帮助您找出工具栏图标或菜单项运行的命令。)
What if you press the wrong key, and something happens to your
buffer—but you're not sure what? Usually, the
safest thing to do is to press C-_
or C-x u (undo). But sometimes this command
won't help, for example, a runaway replace-string. If you remember what you
typed, you can use C-h c (for
describe-key-briefly) to see what
command was run; just retype the offending keystroke(s) at the
prompt, and Emacs responds with the name of the command bound to the
key(s) in the minibuffer. If the command name alone
doesn't help, C-h k
(for describe-key) pops up a
*Help* window with a description of the command as
well as its name and key binding. (C-h
k and C-h c also help you
find out what command a toolbar icon or menu item runs.)
但是,如果您不知道按了哪些键,则可以键入Ch l(对于view-lossage)。这会弹出一个
*Help*窗口,显示您最近输入的 100 次按键;有问题的可能接近尾声,您可以
在这些击键中使用Ch c或Ch k 。
However, if you don't know what keys you pressed,
you can type C-h l (for view-lossage). This pops up a
*Help* window showing the last 100 keystrokes you
typed; the offending ones are likely near the end, and you can use
C-h c or C-h
k with those keystrokes.
现在假设您需要有关不与击键绑定的命令的信息。输入Ch f(表示描述函数)并在提示符下输入命令的名称; Emacs 会显示一个
*Help*包含该命令文档的窗口进行响应。如果您记得命令的名称但忘记了它的绑定,请输入Ch w(表示where-is)。这是Ch c的“相反” ;它显示迷你缓冲区中给定命令的键绑定,或者如果命令没有绑定则显示消息
。command-name
is not on any
keys
Now suppose you want information on a command that
isn't bound to keystrokes. Type C-h f (for describe-function) and enter the name of the
command at the prompt; Emacs responds with a
*Help* window containing the documentation for
that command. If you remember the name of a command but forget its
binding, type C-h w (for where-is). This is the
"opposite" of C-h c; it shows the key binding for a given
command in the minibuffer, or the message
command-name
is not on any
keys if the command has no binding.
您可能会忘记涉及变量值的细节。例如,Emacs 在搜索过程中会尊重还是忽略大小写(变量case-fold-search)?我的缓冲区多久自动保存一次(变量auto-save-interval)?如果您键入Ch v(表示描述变量),后跟变量的名称,Emacs 会将其值及其文档放入窗口中
*Help*。Ch f、Ch w和Ch v都允许您在键入命令或变量名称时使用完成功能。Ch f和Ch v对 Emacs Lisp 程序员也特别有用;请注意,Ch f为您提供有关所有功能的信息
,而不仅仅是那些与按键作为命令绑定的功能。
You may forget a detail that involves the value of a variable. For
example, will Emacs respect or ignore case during a search (the
variable case-fold-search)? How
often are my buffers being auto-saved (the variable auto-save-interval)? If you type C-h v (for describe-variable) followed by the name of the
variable, Emacs puts its value as well as its documentation in a
*Help* window. C-h
f, C-h w, and C-h v all allow you to use completion when
typing command or variable names. C-h
f and C-h v are also
especially useful to Emacs Lisp programmers; note that C-h f gives you information on
all functions, not just those bound to
keystrokes as commands.
当您使用特殊模式(例如 shell 模式或编程语言或文本处理器的模式)时,会出现另一种常见的帮助情况,并且您忘记了特定于该模式的命令或某些其他特征(例如缩进约定)。如果您
在运行该模式的缓冲区中键入Ch m(表示描述模式*Help*),Emacs 会弹出一个窗口,显示该模式的文档。模式的文档通常包括其所有本地键绑定(例如,该模式特有的所有命令及其关联的击键)、自定义变量和其他有趣的特征。
Another common help situation arises when you use a special mode,
such as shell mode or a mode for a programming language or text
processor, and you forget a command specific to that mode or some
other characteristic such as indentation conventions. If you type
C-h m (for describe-mode) in a buffer running the mode,
Emacs pops up a *Help* window showing the
mode's documentation. Documentation for a mode
usually includes all of its local key bindings (for example, all the
commands special to the mode and their associated keystrokes),
customization variables, and other interesting characteristics.
如果您想找出给定模式下可用的所有键盘命令怎么办?Ch b(用于描述绑定)为您提供一个
*Help*窗口,显示当前缓冲区中活动的所有键绑定,包括本地(特定于缓冲区)以及全局键绑定。它还列出了鼠标操作、菜单选项和功能键的所有绑定。
What if you want to find out all the keyboard commands available in a
given mode? C-h b (for describe-bindings) gives you a
*Help* window showing all key
bindings active in the current buffer, including local
(buffer-specific) as well as global ones. It also lists all bindings
for mouse actions, menu options, and function keys.
Ch b产生相当多的输出。如果您想将此输出限制为仅具有特定前缀的键绑定,请键入该前缀,后跟Ch。例如,输入Cx Ch会生成一个窗口,列出以Cx*Help*
开头的所有键绑定。
C-h b produces quite a lot of
output. If you want to limit this output to only those key bindings
with a particular prefix, type that prefix followed by C-h. For example, typing C-x C-h produces a *Help*
window listing all key bindings that begin with C-x.
Ch s(描述语法)是一个更专业的命令,专为 Lisp 程序员设计。它产生一个
当前缓冲区中活动的语法表(参见第 9 章*Help*)的描述
C-h s (for describe-syntax) is a more specialized
command, designed for Lisp programmers. It produces a
*Help* window with a description of the
syntax table (see Chapter 9) active in the current buffer.
另一种类型的帮助命令适用 当您希望 Emacs 执行某些操作,但不确定要使用什么命令或要设置什么变量时。这些是apropos命令,类似于许多图书馆中常见的基本信息检索系统。apropos命令 有多种形式,如表 14-2所示。
Another type of help command applies when you want Emacs to do something, but you're not sure exactly what command to use or what variable to set. These are apropos commands, which resemble a rudimentary information retrieval system of the type found at many libraries. The apropos command has several forms, shown in Table 14-2.
表 14-2。适当的命令
Table 14-2. Apropos commands
|
击键 Keystrokes |
命令名称 Command name |
问题已回答 Question answered |
|---|---|---|
|
查 帮助 → 搜索文档 → 按名称查找命令 C-h a Help → Search Documentation → Find Commands by Name |
apropos 命令 apropos-command |
哪些命令包含这个词? What commands include this word? |
|
(无) 帮助 → 搜索文档 → 按名称查找选项 (none) Help → Search Documentation → Find Options by Name |
apropos 变量 apropos-variable |
哪些变量包含此正则表达式? What variables include this regular expression? |
|
(无) 帮助 → 搜索文档 → 按值查找选项 (none) Help → Search Documentation → Find Options by Value |
适当的价值 apropos-value |
该正则表达式设置了哪些变量? What variables are set to this regular expression? |
|
(无) 帮助 → 搜索文档 → 搜索文档字符串 (none) Help → Search Documentation → Search Documentation Strings |
适当的文档 apropos-documentation |
文档中哪里提到了这个正则表达式? Where is this regular expression mentioned in the documentation? |
|
(无) 帮助 → 搜索文档 → 按名称查找任何对象 (none) Help → Search Documentation → Find Any Object by Name |
恰到好处 apropos |
该正则表达式涉及哪些函数和变量? What functions and variables involve this regular expression? |
所有apropos命令都会提示输入正则表达式(普通文本字符串也可以,但您可以使用正则表达式创建更强大的搜索;有关详细信息,请参阅第 11 章)。当您键入Ch a并后跟正则表达式时,Emacs 会查找与其匹配的所有命令;它*Apropos*在 Apropos 模式下的窗口中显示其键绑定(如果有)及其文档的第一行
。此模式显示超链接帮助。如果您使用鼠标中键单击粗体项目或将光标移至此处并按Enter 键,Emacs 将显示更多信息。
All apropos commands prompt for
regular expressions (an ordinary text string will work, but you can
create more powerful searches using regular expressions; see Chapter 11 for details). When you type C-h a followed by a regular expression, Emacs
finds all the commands that match it; it displays their key bindings
(if any) and the first lines of their documentation in an
*Apropos* window that is in Apropos mode. This
mode displays hyperlinked help. If you click on a bolded item using
your middle mouse button or move the cursor there and press Enter, Emacs displays more information.
与往常一样,如果您对使用正则表达式持谨慎态度,请使用常规搜索字符串,只要坚持使用非特殊字符即可。例如,如果您想知道 Emacs 支持哪些替换命令,请按Ch a,然后输入Replace; Emacs 显示有关以下命令的信息列表:
As always, if you are leery of using regular expressions, use regular search strings as long as you stick to nonspecial characters. For example, if you want to know what replace commands Emacs supports, press C-h a and then type replace; Emacs displays a list of information on the following commands:
直接执行查询替换
dired-do-query-replace
浏览标签查询替换
ebrowse-tags-query-replace
埃塞俄比亚-替换-空间
ethio-replace-space
映射查询替换正则表达式
map-query-replace-regexp
查询-替换
query-replace
查询替换正则表达式
query-replace-regexp
查询替换正则表达式评估
query-replace-regexp-eval
在 Windows 中替换缓冲区
replace-buffer-in-windows
替换矩形
replace-rectangle
替换正则表达式
replace-regexp
替换字符串
replace-string
标签查询替换
tags-query-replace
如果您曾经使用过信息检索系统,您就会知道有效使用此类系统需要一些技能。您需要仔细选择您的概念(搜索字符串),以便它们不会太笼统(输出太多而费力)或太具体(输出太少,使您不太可能获得所需的信息)。当您使用apropos命令时,这个问题会变得更加复杂,该命令与apropos-command相同,只是它报告所有函数(包括内部 Emacs 函数)和变量以及命令。
If you have ever used an information retrieval system, you already know that some skill is needed to use such a system effectively. You need to choose your concepts (search strings) carefully, so that they aren't too general (too much output to wade through) or too specific (too little output, making it less likely that you get the information you want). This problem is compounded when you use the apropos command, which is the same as apropos-command except that it reports on all functions (including internal Emacs functions) and variables as well as commands.
如果您输入的搜索字符串过于笼统,Emacs 会生成大量帮助信息缓冲区。例如,使用参数“buffer”调用apropos-command会导致输出列出超过 200 个 Emacs 命令。一般来说,您可能需要调用apropos命令几次才能获取所需的信息(在大小和相关性方面)。
If you type in a search string that is too general, Emacs produces an enormous buffer of help information. For example, invoking apropos-command with the argument "buffer" results in output listing well over two hundred Emacs commands. In general, you may have to invoke the apropos commands a few times to get the information you want (in terms of size as well as relevance).
apropos命令本身通常是多余的,除非你是一个 Lisp 程序员,需要有关非命令函数的信息(有关apropos使用的详细信息,请参阅第 11 章)。尽可能使用更具体的命令。例如,要获取有关变量的信息,请使用apropos-variable。要了解与自动保存相关的变量,请输入Mx apropos-variable Enter auto-save Enter。 Emacs 响应有关变量auto-save-default、auto-save-file-format、auto-save-file-name-transforms、auto-save-interval、auto-save-list-file-prefix、auto-save的信息-timeout、auto-save-visited-file-name和delete-auto-save-files。要查找这些变量之一的值和完整描述,请移至窗口
并单击鼠标中键,或移至所需变量并按Enter。*Apropos*
The apropos command itself is
usually overkill, unless you are a Lisp programmer who needs
information on noncommand functions (see Chapter 11 for details on this use of apropos). Use a more specific command when
possible. For example, to get information on variables, use apropos-variable. To find out about variables
related to auto-saving, type M-x
apropos-variable Enter auto-save Enter. Emacs responds
with information about the variables auto-save-default, auto-save-file-format, auto-save-file-name-transforms, auto-save-interval, auto-save-list-file-prefix, auto-save-timeout, auto-save-visited-file-name, and delete-auto-save-files. To find the value and
full description of one of these variables, move to the
*Apropos* window and either click with the middle
mouse button or move to the desired variable and press Enter.
许多更多 复杂的 Emacs 命令包括它们自己的帮助按键集。这些命令通常有自己的帮助功能,但帮助是通过?调用的。而不是标准的帮助键。这里总结了一些流行的复杂命令还有哪些?其中每个人的作用是:
Many of the more complicated Emacs commands include their own sets of help keystrokes. These commands often have their own help functionality, but help is invoked with ? rather than the standard help key. Here is a summary of some popular complex commands and what ? does within each of them:
您会在迷你缓冲区中看到最常用命令的列表。这份清单还远未完成。输入 Ch m(用于描述模式)以获得更全面的文档,输入Ch b(用于 描述绑定)以获取所有可用的键绑定。
You see a list of the most frequently used commands in the minibuffer. This list is far from complete. Type C-h m (for describe-mode) for more comprehensive documentation and C-h b (for describe-bindings) for all the key bindings available to you.
您会看到一个*Help*
列出可用命令的窗口。键入Ch会执行相同的操作。这也适用于
query-replace-regexp。
You see a *Help*
window listing the available commands. Typing C-h does the same thing. This also works with
query-replace-regexp.
行为类似于刚刚描述的查询替换 。
Behavior is similar to query-replace just described.
您会看到一个*Help*窗口,提供有关缓冲区菜单模式的信息。此命令与键入Ch m(对于描述模式)具有相同的效果
。
You see a *Help* window giving information on
buffer menu mode. This command has the same effect as typing
C-h m (for describe-mode).
当您响应带有 Emacs 可以完成的内容名称的迷你缓冲区提示时,输入?随时为您提供一个
*Completions*窗口,其中包含当时可用的选择。本章稍后将详细解释完成操作。
When you are responding to a minibuffer prompt with the name of
something on which Emacs can do completion, typing ? at any time gives you a
*Completions* window with the choices available at
that point. Completion is explained in detail later in this chapter.
曾几何时,为了访问 Emacs 文档,您从 FSF 订购了手册。如果您喜欢印刷文档(就像我们一样)并且愿意支持 FSF,您仍然可以这样做,但您想要或需要的大多数文档都可以在 Emacs 中触手可及。
Once upon a time, to get access to Emacs documentation, you ordered manuals from FSF. You can still do so if you like printed documentation (as we do) and would like to support the FSF, but most of the documentation you will ever want or need is at your fingertips right in Emacs.
大多数 GNU 文档(包括 Emacs 文档)都是 texinfo 格式,旨在在 Info 文档阅读器中阅读。输入Ch i(对于info)会将您置于信息树的顶层。您会发现 Emacs 只是众多选择之一。在 Info 中,文档被组织为 称为节点的信息 树。如果您想要有关某个主题的信息,您可以选择其树;树的节点包含有关子主题、子子主题等的信息,按层次结构组织。
Most GNU documentation (including Emacs documentation) is in texinfo format and designed to be read in the Info documentation reader. Typing C-h i (for info) puts you at the top-level of the Info tree. You'll see that Emacs is just one choice of many. In Info, documentation is organized as trees of information called nodes. If you want information on a topic, you can select its tree; the nodes of the tree contain information on subtopics, subsubtopics, etc., organized hierarchically.
当您键入Ch i时,您会在 Info 模式下的窗口中看到一个包含Info系统目录节点 的只读缓冲区。如果您在 Info中按h键,您将获得一份有关Info的教程 ,类似于前面介绍的基本 Emacs 命令。
When you type C-h i, you see a read-only buffer containing the directory node of the Info system in a window in Info mode. If you press h while in Info, you get a tutorial on Info analogous to the one described earlier for basic Emacs commands.
您最好输入Ch r,它会将您直接转至 Emacs 手册。
You're probably better off typing C-h r, which sends you directly to the Emacs manual.
请注意,信息模式下的图标几乎完全不同。在本节后面,表 14-3列出了它们,以及在此模式下导航所需的按键。
Note that the icons are almost completely different in Info mode. Later in this section, Table 14-3 lists them, along with the keystrokes needed for navigating in this mode.
信息相对简单,但也足够复杂,有自己的教程。键入h会带您浏览一个教程,以熟悉主要命令。
Info is relatively simple, yet complex enough to have its own tutorial. Typing h sends you through a tutorial to acquaint you with the main commands.
要选择菜单选项(您会 在这些选项旁边看到一个* ),请移至该选项。显然,用鼠标移动是一种方法;然后使用鼠标中键选择该选项。或者,通过按Tab移至该选项,然后按Enter。
To select a menu option (you see a * next to these), move to that option. Obviously, moving with the mouse is one method; you then select the option using the middle mouse button. Alternatively, move to the option by pressing Tab, and then press Enter.
|
移至 Minibuffer(您需要向下滚动),然后按Enter。 Move to Minibuffer (you'll need to scroll down), and then press Enter. |
|
|
|
将出现“迷你缓冲区”主题。 The Minibuffer topic appears. |
如果您想阅读整个主题,可以按空格键向下滚动。空格有助于连续阅读,因为完成一个主题后,它会将您移至该级别的下一个节点。如果您阅读了本主题的全部内容,您将比您想象的更多地了解迷你缓冲区。
If you want to read through the whole topic, you can press Space to scroll down. Space is helpful for continuous reading because after you complete a topic, it moves you to the next node at this level. If you read all of this topic, you'll learn more about the minibuffer than you ever thought possible.
如果按u两次(向上移动一级),您将返回到 Emacs 目录。工具栏上的向上箭头图标具有相同的作用。要通过一次击键来完成此操作,请输入t(表示Info-top-node)或单击房屋工具栏图标。无论您在信息树中走了多远,该命令都会将您一步带到顶层。
If you press u twice (to move up a level), you'll move back to the Emacs table of contents. The up arrow icon on the toolbar does the same thing. To accomplish this with a single keystroke, type t (for Info-top-node) or click on the house toolbar icon. That command takes you to the top level in one move, no matter how far down the Info tree you've traveled.
要搜索特定主题,请输入i或单击显示手指指向一张纸的工具栏图标。
To search for a particular topic, type i or click on the toolbar icon that shows a finger pointing at a piece of paper.
|
输入逗号:, Type a comma: , |
|
|
|
Emacs 转到索引中的下一个与宏相关的主题。 Emacs moves to the next macro-related topic in the index. |
当您以这种方式逐步浏览索引条目时,查看屏幕顶部以了解您所在的主题会很有帮助。您可能想要向上移动一个节点(或到上一个或下一个节点)以获得更好的结果查看当前主题,而不是通过键入另一个逗号导航到下一个索引条目。
As you step through index entries in this way, it's helpful to look at the top of the screen to see what topic you're in. You might want to move up a node (or to the previous or next node) to get a better view of the topic at hand rather than navigating to the next index entry by typing another comma.
浏览信息需要一些练习。例如,人们可能会认为命令p(表示 Info-prev)[ 1 ]的行为很像 Web 浏览器后退按钮(特别是考虑到该命令的工具栏图标看起来像一个)。在这种情况下,前一个意味着相对于信息文档树,而不是相对于您的会话(尽管有时可能会出现这种情况)。这意味着您要移至此级别的上一个项目。要返回到会话中的上一个屏幕,请使用l(表示Info-last),它在工具栏上显示为带有弯曲箭头图标(类似于其他模式中用于撤消的图标)。此命令的行为类似于 Web 浏览器后退按钮。
Navigating through Info can take some practice. For example, one might think that the command p (for Info-prev)[1] would behave rather like a web browser back button (especially given that the toolbar icon for this command looks like one). Previous in this case means relative to the Info documentation tree, not to your session (though it may appear that way sometimes). It means that you want to move to the previous item at this level. To move back to the previous screen in your session, use l (for Info-last), shown on the toolbar with a curved arrow icon (like the icon for undo in other modes). This command behaves like a web browser back button.
命令Ch F(对于Info-goto-emacs-command-node)和Ch K(对于Info-goto-emacs-key-command-node)可让您 以更集中的方式使用Info 。它们本质上分别是Ch f(对于描述函数)和Ch k(对于描述键)的 Info等价物:它们启动 Info系统并直接转到命令(对于Ch F)或击键的文档(s)(对于Ch K)您作为参数给出。
The commands C-h F (for Info-goto-emacs-command-node) and C-h K (for Info-goto-emacs-key-command-node) let you use Info in a more focused way. They are essentially the Info equivalents of C-h f (for describe-function) and C-h k (for describe-key), respectively: they start up the Info system and go directly to the documentation for the command (for C-h F) or the keystroke(s) (for C-h K) you give as an argument.
表 14-3。信息命令
Table 14-3. Info commands
|
击键 Keystrokes |
工具栏图标 Toolbar icon |
命令名称 Command name |
行动 Action |
|---|---|---|---|
|
标签 Tab |
信息下一个参考 Info-next-reference |
移至下一个菜单项或交叉引用。 Move to the next menu item or cross-reference. | |
|
空间 Space |
信息向上滚动 Info-scroll-up |
滚动屏幕;完成后移至此级别的下一个主题。 Scroll the screen; move to the next topic at this level when finished. | |
|
删除 或 翻页 Del or PgUp |
信息向下滚动 Info-scroll-down |
向后滚动。 Scroll backward. | |
|
p p |
|
信息上一页 Info-prev |
移至此级别的上一个主题(不像浏览器后退按钮)。如果没有之前的主题,则升级一个级别。 Move to the previous topic at this level (not like a browser back button). If there is no previous topic, move up a level. |
|
你 u |
|
信息更新 Info-up |
提升一个级别。 Move up a level. |
|
n n |
|
信息下一个 Info-next |
转到此级别的下一个主题。 Move to the next topic at this level. |
|
我 i |
|
信息索引 Info-index |
在索引中搜索主题。 Search the index for a topic. |
|
, , |
信息索引下一个 Info-index-next |
转到索引中的下一个主题。 Go to the next topic in the index. | |
|
米 m |
信息菜单 Info-menu |
通过键盘选择菜单项。 Select a menu item through the keyboard. | |
|
q q |
|
信息出口 Info-exit |
退出信息。 Quit info. |
|
s s |
|
信息搜索 Info-search |
搜索正则表达式。 Search for a regular expression. |
|
G g |
|
信息转到节点 Info-goto-node |
前往指定节点。 Go to a specified node. |
|
t t |
|
信息顶级节点 Info-top-node |
转到顶部节点。 Go to the top node. |
|
我 l |
|
信息最后 Info-last |
转到您访问的最后一个节点(如浏览器后退按钮)。 Go to the last node you visited (like a browser back button). |
|
H h |
信息帮助 Info-help |
开始信息教程。 Start the info tutorial. |
要显示常见问题 (FAQ) 文件,请键入Ch f。该文件为 Info 格式。
To display the Frequently Asked Questions (FAQ) file, type C-h f. This file is in Info format.
也许是对于铁杆用户和定制者来说,剩下的 Emacs 帮助命令中最重要的是Ch n(用于view-emacs-news),它访问 Emacs 附带的NEWS文件。该文件包含自上一个主要版本以来 Emacs 所做的更改历史记录;例如,版本 20.1 中的所有更改以及最新次要版本的后续版本(在我们的示例中为版本 21.3.5,尽管文件显示为 21.4)。如果自上一个主要版本以来已经有多个次要版本,则这可能是一个非常长的文件 - 在我们的例子中,该文件有 12,886 行长。如果您想查看 Emacs 特定方面的更改,请使用适当的搜索命令。但如果您只是想浏览一下,请注意该文件旨在与大纲模式一起使用:主题在以*开头的行上引入,子主题在以**开头的行上引入。使用大纲模式命令浏览文件;有关信息,请参阅第 7 章。大纲模式命令hide-body 显示主要主题并隐藏文本;show-all也会重新显示所有文本。
Perhaps the most important of the remaining Emacs help commands for hard-core users and customizers is C-h n (for view-emacs-news), which visits the NEWS file that comes with Emacs. This file contains a history of changes made to Emacs since the last major version; for example, all changes in Version 20.1 and following up to the latest minor version (which in our case is Version 21.3.5, though the file says 21.4). This can be a very long file if there have been several minor releases since the last major version—in our case, the file is 12,886 lines long. If you want to look through it for changes to a specific aspect of Emacs, use an appropriate search command. But if you just want to skim it, note that this file was intended for use with outline mode: topics are introduced on lines beginning with *, and subtopics are introduced on lines beginning with **. Use outline mode commands to skim the file; see Chapter 7 for information. The outline mode command hide-body displays the main topics and hides the text; show-all redisplays all the text as well.
了解最新版本的一种有趣方法是反新闻。该文件认为 Emacs 已降级,在我们的例子中从 21.4 降级到 21.3。它带您了解从 Emacs 21.4 中剥离出来以创建 Emacs 21.3 的所有功能。 Antinews 是 Emacs 手册第一页上的一个菜单项,您可以通过Ch r访问。
An entertaining approach to learning about the latest release is Antinews. This file takes the viewpoint that Emacs has been downgraded, in our case from 21.4 to 21.3. It takes you through all the features that have been ripped from Emacs 21.4 to create Emacs 21.3. Antinews is a menu item on the first page of the Emacs manual you reach via C-h r.
表 14-4总结了与阅读文档、获取有关 Emacs 的一般信息以及语言编码问题相关的命令。
Table 14-4 summarizes commands relating to reading documentation, getting general information about Emacs, and language encoding issues.
表 14-4。文档、一般信息和编码选项
Table 14-4. Documentation, general information, and encoding options
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
Ch t 帮助 → Emacs 教程 C-h t Help → Emacs Tutorial |
教程帮助 help-with-tutorial |
运行 Emacs 教程。 Run the Emacs tutorial. |
|
气 C-h i |
信息 info |
启动信息文档阅读器。如果以Cu开头,则读取您选择的信息文件。 Start the Info documentation reader. If prefaced with C-u, reads an Info file of your choice. |
|
Ch r 帮助 → 阅读 Emacs 手册 C-h r Help → Read the Emacs Manual |
信息 emacs 手册 info-emacs-manual |
打开 Emacs 手册。 Opens the Emacs manual. |
|
Ch F 帮助 → 更多手册 → 在手册中查找命令 C-h F Help → More Manuals → Find Command in Manual |
信息-转到-emacs-命令节点 Info-goto-emacs-command-node |
在讨论此命令的节点启动信息文档阅读器。 Start Info documentation reader at the node that discusses this command. |
|
Ch K 帮助 → 更多手册 → 在手册中查找密钥 C-h K Help → More Manuals → Find Key in Manual |
信息-goto-emacs-key-command-node Info-goto-emacs-key-command-node |
在讨论此键序列的节点启动信息文档阅读器。 Start Info documentation reader at the node that discusses this key sequence. |
|
Ch n 或 C-h Cn 帮助 → Emacs 新闻 C-h n or C-h C-n Help → Emacs News |
查看 emacs 新闻 view-emacs-news |
查看有关 Emacs 最新更改的新闻。 View news about recent changes in Emacs. |
|
Ch Cf 帮助 → Emacs 常见问题解答 C-h C-f Help → Emacs FAQ |
查看-emacs-常见问题解答 view-emacs-FAQ |
查看有关 Emacs 的常见问题及其解答的文件。 View a file of frequently asked questions and their answers about Emacs. |
|
(无) 帮助 → 搜索文档 → Emacs 术语 (none) Help → Search Documentation → Emacs Terminology |
搜索-emacs-术语表 search-emacs-glossary |
打开 Emacs 术语词汇表。 Open a glossary of Emacs terms. |
|
(无) 帮助 → 搜索文档 → 在用户手册中查找主题 (none) Help → Search Documentation → Look Up Subject in User Manual |
emacs-索引-搜索 emacs-index-search |
搜索 Emacs 用户手册的索引。 Search the index of the Emacs user manual. |
|
(无) 帮助 → 搜索文档 → 在 ELisp 手册中查找主题 (none) Help → Search Documentation → Look Up Subject in ELisp Manual |
elisp 索引搜索 elisp-index-search |
搜索 Emacs Lisp 手册的索引。 Search the index of the Emacs Lisp manual. |
|
Ch 输入 帮助 → 更多手册 → 订购手册 C-h Enter Help → More Manuals → Ordering Manuals |
查看订单手册 view-order-manuals |
显示有关订购印刷手册的信息。 Displays information about ordering print manuals. |
|
CHp C-h p |
按关键字查找 finder-by-keyword |
调用一个菜单,让您获取有关系统上可用的 Emacs Lisp 软件包的信息。 Invoke a menu that lets you get information about Emacs Lisp packages available on your system. |
|
Ch Cc 帮助 → 复制条件 C-h C-c Help → Copying Conditions |
描述复制 describe-copying |
查看通用公共许可证 (GPL)。 View the General Public License (GPL). |
|
Ch Cd 帮助 → 获取新版本 C-h C-d Help → Getting New Versions |
描述分布 describe-distribution |
查看有关从 FSF 订购 Emacs 的信息。 View information on ordering Emacs from FSF. |
|
氯磷 C-h C-p |
描述项目 describe-project |
查看有关 GNU 项目的信息。 (见前言。) View information on the GNU project. (See the Preface.) |
|
Ch Cw 帮助 → (非)保修 C-h C-w Help → (Non)Warranty |
描述无保证 describe-no-warranty |
查看 Emacs 的(非)保修。 Emacs 不提供保证,因此得名。 View the (non-)warranty for Emacs. Emacs doesn't provide a warranty, hence the name here. |
|
ChCT C-h C-t |
查看待办事项 view-todo |
如果您是一名希望为 Emacs 代码库做出贡献的程序员,请使用此命令查看需要完成的操作列表。 If you're a programmer looking to contribute to the Emacs code base, use this command to view a list of what needs to be done. |
|
Ch Ce 帮助 → Emacs 已知问题 C-h C-e Help → Emacs Known Problems |
查看 emacs 问题 view-emacs-problems |
显示PROBLEMS文件,其中包括已知问题的列表。 Displays the PROBLEMS file, which includes a list of known problems. |
|
CH C-h h |
查看你好文件 view-hello-file |
查看HELLO文件,该文件以多种语言显示“hello”一词。 View the HELLO file, which displays the word "hello" in numerous languages. |
|
Ch L 帮助 → 描述 → 描述语言环境 C-h L Help → Describe → Describe Language Environment |
描述语言环境 describe-language-environment |
提示输入默认值(当前环境)或列出可能的完成情况。菜单选项显示这些选择。 Prompts for either default (current environment) or lists possible completions. Menu option shows these choices. |
|
Ch I 或 C-h C-\ 帮助 → 描述 → 描述输入法 C-h I or C-h C-\ Help → Describe → Describe Input Method |
描述输入法 describe-input-method |
显示当前输入法(默认)或完成后显示可能的输入法列表。 Shows current input method (the default) or, with completion, a list of possible input methods. |
|
Ch C 帮助 → 描述 → 描述编码系统 C-h C Help → Describe → Describe Coding System |
描述编码系统 describe-coding-system |
显示当前编码系统(默认),或者在完成后列出所有可用的编码系统。 Shows current coding system (the default) or, with completion, lists all available coding systems. |
我们看到一个 第 1 章中 Emacs 完成功能的示例。补全不仅仅是一个功能:它是 Emacs 设计中的一般原则。它可以表述如下:
We saw an example of Emacs's completion facility in Chapter 1. Completion is more than just a feature: it is a general principle in the design of Emacs. It can be articulated as follows:
如果您必须输入某个名称,并且该名称是有限数量的可能性之一,那么 Emacs 应该在尽可能少的击键次数后弄清楚您的意思。
If you have to type in the name of something, and that name is one of a finite number of possibilities, Emacs should figure out what you mean after the smallest possible number of keystrokes.
换句话说,您可以输入最短的明确前缀并告诉 Emacs 计算出名称的其余部分。通过“最短的明确前缀”,我们的意思是“名称足够多,从头开始,以将其与其他可能性区分开来”。 Emacs 中的一些重要事物的名称是从有限数量的可能性中选择的,包括以下内容:
In other words, you can type in the shortest unambiguous prefix and tell Emacs to figure out the rest of the name. By "shortest unambiguous prefix," we mean "enough of the name, starting from the beginning, to distinguish it from the other possibilities." Several important things in Emacs have names that are chosen from a finite number of possibilities, including the following:
命令
Commands
给定目录中的文件
Files in a given directory
缓冲器
Buffers
Emacs 变量
Emacs variables
大多数时候,当系统提示您输入迷你缓冲区中某个内容的名称时,即可完成。当您输入名称时,您可以使用三个键告诉 Emacs 帮助您完成名称:Tab、Space和问号 ( ? )。其功能如表14-5所示。
Most of the time, completion is available when you are prompted for a name of something in the minibuffer. While you are typing in the name, you can use three keys to tell Emacs to help complete it for you: Tab, Space, and question mark (?). Their functions are shown in Table 14-5.
表 14-5。完成键
Table 14-5. Completion keys
|
按键 Keystroke |
行动 Action |
|---|---|
|
标签 Tab |
尽可能完成名称。 Completes the name as far as possible. |
|
空间 Space |
将名称补全到下一个标点符号。 Completes the name out to the next punctuation character. |
|
? ? |
在窗口中列出此时的选择 Lists the choices at this point in a |
您可能会发现Tab最有用。
You will probably find Tab to be the most useful.
作为一个运行示例,假设您已键入Cx Cf来访问文件,并且您要访问的文件是一个名为program.c的 C 程序。假设您输入pro并按Tab; Emacs 通过将名称补全为完整的program.c进行响应。如果按空格键,Emacs 只会完成 程序。 Emacs 完成名称后,您可以按Enter来访问该文件。
As a running example, assume you have typed C-x C-f to visit a file, and the file you want to visit is a C program called program.c. Let's say you type pro and press Tab; Emacs responds by completing the name to the full program.c. If you press Space, Emacs completes only as far as program. After Emacs completes the name, you can press Enter to visit the file.
在使用补全功能之前,您需要输入多少姓名?这取决于给定情况下其他可能的选择。如果program.c是目录中的唯一文件,您只需键入p并按Tab即可。[ 2 ]如果您的目录中还有其他文件,并且它们的名称都没有以p开头,您可以执行相同的操作。但是,如果您有一个名为Problem.c的文件,则必须在按 Tab 键之前输入prog ;在这种情况下,prog是最短的明确前缀。如果您只是输入pro并按Tab,Emacs 会显示一个
*Completions*窗口,其中包含完成选项列表(在本例中为program.c和
Problem.c ),并将光标返回到迷你缓冲区,以便您可以完成文件名的输入。如果您键入问号而不是Tab ,也会发生同样的情况。此时可以输入g并再次按Tab键; Emacs 将名称补全为
program.c。
How much of the name do you need to type in before you can use
completion? That depends on the other possible choices in the given
situation. If program.c were the only file in
your directory, you could just type p and press Tab.[2] If there were
other files in your directory and none of them has a name beginning
with p, you could do the same thing.
But if you had a file called problem.c, you
would have to type prog before you
pressed Tab; in this case, prog is
the shortest unambiguous prefix. If you just type in pro and press Tab, Emacs responds with a
*Completions* window containing a list of the
completion choices, in this case program.c and
problem.c, and returns your cursor to the
minibuffer so that you can finish typing the filename. The same thing
happens if you typed a question mark instead of Tab. At this point, you can type g and press Tab again; Emacs completes the name to
program.c.
再举一个例子,假设您的 C 程序文档位于文件program.txt中,并且您想要访问它。您按Cx Cf并在提示符下键入prog ,然后键入Tab。 Emacs 完成编程.. 此时,您可以输入t并再次按Tab; Emacs 完成整个 program.txt。换句话说,您可以在指定名称时重复使用补全。
As another example, let's say you have documentation for your C program in the file program.txt, and you want to visit it. You press C-x C-f and type prog at the prompt, followed by Tab. Emacs completes out to program.. At this point, you can type t and press Tab again; Emacs completes the entire program.txt. In other words, you can use completion repeatedly when specifying a name.
最后,假设您的目录中还有一个名为 simple program 的文件,它是编译 C 文件的结果,但您仍然想访问文档文件。输入prog
并按Tab; Emacs 完成编程。 (包括期间)。此时,Tab和Space做不同的事情。如果您再次按
Tab[Complete, but not unique] ,Emacs 会在迷你缓冲区中以消息进行响应,但如果您按Space ,Emacs 会假定您对文件程序不感兴趣
并尝试进一步完成。因为您有文件program.c和
program.txt,Emacs 只完成
program .,您必须键入t并再次按Tab键。
Finally, let's say you also have a file in your
directory called simply program, which is the
result of compiling your C file, but you still want to visit the
documentation file. You type prog
and press Tab; Emacs completes out
to program. (including the period). At this
point, Tab and Space do different things. If you press
Tab again, Emacs responds with the
message [Complete, but not unique] in the
minibuffer, but if you press Space,
Emacs assumes you aren't interested in the file
program and attempts to complete further.
Because you have the files program.c and
program.txt, Emacs only completes out to
program., and you have to type t and press Tab again.
补全的工作方式与缓冲区名称相同,例如,当您键入Cx b切换到当前窗口中的另一个缓冲区时。当您键入Mx时,它还可以使用命令名称,但增加了一项功能。请注意,当您指定文件或缓冲区名称时,您想要的文件或缓冲区可能尚不存在(例如,当您要创建新文件时)。当然,在这种情况下,您必须输入整个文件或缓冲区名称,然后按Enter。但是,当您为命令键入 Mx时,该命令不可能不存在。因此,当您按Enter时,Emacs 会自动尝试完成命令名称。
Completion works the same way with buffer names, for example, when you type C-x b to switch to another buffer in the current window. It also works with command names when you type M-x—but with one added feature. Notice that when you specify a file or buffer name, it is possible that the file or buffer you want doesn't yet exist (for example, when you want to create a new file). In this case, of course, you must type in the entire file or buffer name and press Enter. But when you type M-x for a command, there is no possibility of the command not existing. Therefore, Emacs automatically attempts to do completion on command names when you press Enter.
例如,如果您想将文本文件的缓冲区设置为自动填充模式(请参阅第 2 章),则可以键入Mx auto-f并按Enter键,而不是键入整个Mx auto-fill-mode。如果您输入命令名称的非唯一(不明确)前缀(例如,如果您输入
Mx aut)并按Enter,则Enter 的作用就像Tab一样;在这种情况下,它完成为
auto。如果再次按Enter,Emacs 会响应一个
*Completions*列出选项的窗口。要获得
auto-fill-mode,您必须输入
f并再次按Enter键。
For example, if you want to put a buffer for a text file in auto-fill
mode (see Chapter 2), you can type M-x auto-f and press Enter instead of typing the entire M-x auto-fill-mode. If you type in a nonunique
(ambiguous) prefix of a command name—for example, if you type
M-x aut—and press Enter, then Enter acts just like Tab; in this case, it completes out to
auto. If you press Enter again, Emacs responds with a
*Completions* window listing the choices. To get
auto-fill-mode, you have to type
f and press Enter again.
使用Enter完成命令名称非常方便。使用 Emacs 一段时间后,您将熟悉经常使用的命令的最短无歧义前缀,并且使用这些前缀而不是全名可以节省大量的打字时间。[ 3 ]
Completion on command names with Enter is very convenient. After you have used Emacs for a while, you will become familiar with the shortest unambiguous prefixes for commands you use often, and you can save a considerable amount of typing by using these prefixes instead of the full names.[3]
Emacs 还可以对 Emacs 变量的名称进行补全。在 第 2 章和其他地方,我们了解了如何使用Mx set-variable来更改 Emacs 变量的值。刚刚描述的Enter功能 适用于变量和命令;因此,在执行Mx set-variable时,您可以使用完成功能,包括Enter。实际上,命令和变量都是 Emacs Lisp符号的特殊类型,Emacs 可以对所有类型的 Lisp 符号进行Enter补全。当您使用本章前面描述的一些帮助命令时,Lisp 符号的补全会派上用场。
Emacs can also do completion on the names of Emacs variables. In Chapter 2, and elsewhere, we saw how you can use M-x set-variable to change the values of Emacs variables. The Enter feature just described works on variables as well as commands; therefore, you can use completion, including Enter, when doing M-x set-variable. Actually, commands and variables are both special kinds of Emacs Lisp symbols, and Emacs can do completion with Enter on all kinds of Lisp symbols. Completion on Lisp symbols comes in handy when you are using some of the help commands described earlier in this chapter.
如果您已阅读第 10 章并且
熟悉设置 Emacs 变量后,您应该知道一些变量可以自定义 Emacs 完成的方式。变量completion-auto-help决定
*Completions*当您尝试在不明确的前缀上使用空格或制表符时是否自动显示窗口。它的默认值是
t,这意味着这样的窗口会自动出现。如果将其设置为nil*Completions* ,则Emacs 只会在迷你缓冲区中显示消息[Next
char not
unique]几秒钟,而不是
出现窗口。
If you have read Chapter 10 and are
comfortable
with setting Emacs variables, you should know that a few variables
can customize the way Emacs does completion. The variable completion-auto-help determines whether a
*Completions* window automatically appears when
you try to use Space or Tab on an ambiguous prefix. Its default is
t, meaning that such windows
automatically appear. If you set it to nil, instead of a
*Completions* window appearing, Emacs just
displays the message [Next
char not
unique] for a couple of seconds in the minibuffer.
如果您是程序员或者使用像 LATEX 这样的文本格式化程序,您将创建不适合人类阅读的文件,例如编译器创建的目标文件和文本格式化程序创建的打印文件。理想情况下,您不希望 Emacs 在您完成补全时打扰这些文件。例如,如果您有文件program.c和
program.o(编译器的目标代码输出),您希望Emacs 只识别前者。 Emacs 确实有一个功能可以处理这个问题;事实上,您可能已经注意到,在这种情况下,如果您键入program并按Tab,Emacs 会忽略
program.o并完成为
program.c。变量completion-ignored-extensions控制这一点;它是 Emacs 在文件名完成过程中忽略的文件名后缀列表。默认情况下,该列表包括~用于 Emacs 备份文件的波形符 ( )、
用于程序员的.o、用于用户的各种后缀、
用于 Emacs 定制程序的.elc(字节编译的 Emacs Lisp)等。 (当然,如果您确实想查看这些文件,可以手动输入它们的名称。)
If you are a programmer or if you use text formatters like LATEX ,
you will create files that are not meant for humans to read, such as
object files created by compilers and print files created by text
formatters. Ideally, you wouldn't want Emacs to
bother with these files when you are doing completion; for example,
if you have the files program.c and
program.o (object-code output from the
compiler), you want Emacs to recognize only the former. Emacs does
have a feature that deals with this; indeed, you may already have
noticed that in this kind of situation, if you type program and press Tab, Emacs ignores
program.o and completes out to
program.c. The variable completion-ignored-extensions controls this;
it is a list of filename suffixes that Emacs ignores during filename
completion. By default, the list includes tilde
(~) for Emacs backup files,
.o for programmers, various suffixes for users,
.elc (byte-compiled Emacs Lisp) for Emacs
customizers, and others. (Of course, if you really want to look at
these files, you can type their names manually.)
您可以通过在.emacs文件中放入以下形式的行,将自己的“忽略”后缀添加到列表中 :
You can add your own "ignored" suffix to the list by putting a line of this form in your .emacs file:
(setq 完成-忽略-扩展
(缺点“ suffix”完成忽略扩展))(setq completion-ignored-extensions
(cons "suffix" completion-ignored-extensions))例如,假设您正在使用打印 PostScript 的打印机进行文本处理,并且您的文本处理器生成后缀为.ps 的打印文件。如果您不想查看这些文件,请将以下行放入您的.emacs文件中:
For example, let's say you are doing text processing with a printer that prints PostScript, and your text processor produces print files with the suffix .ps. If you don't want to look at these files, put the following line in your .emacs file:
(setq 完成-忽略-扩展
(缺点“.ps”完成忽略扩展))(setq completion-ignored-extensions
(cons ".ps" completion-ignored-extensions))最后,您可以通过将变量completion-ignore-case设置为t (或nil以外的任何值)来告诉Emacs在完成完成时忽略大小写区别。它的默认值是nil,这意味着 Emacs 尊重大小写区别。
Finally, you can tell Emacs to ignore case distinctions when doing completion by setting the variable completion-ignore-case to t (or any value other than nil). Its default value is nil, meaning that Emacs respects case distinctions.
本附录列出了一些 Emacs 变量。我们选择它们是因为它们具有普遍的实用性以及它们对本书主题的适用性。
This appendix lists some Emacs variables. We chose them for their general usefulness and for their applicability to subjects in this book.
下面的变量按类别分组,并显示它们的默认值(在可行的情况下)。有关特定变量的更多详细信息,请参阅每个表开头引用的章节。为了 有关编程语言模式中使用的变量的信息,请参阅第 9 章。
The variables below are grouped by category, and their default values are shown (where practical to do so). For more details on specific variables, see the chapters referred to at the beginning of each table. For information on variables used in programming language modes, see Chapter 9.
表 A-1。备份、自动保存和版本控制(第 2 章、第 12 章)
Table A-1. Backups, auto-save, and versioning (Chapter 2, Chapter 12)
|
多变的 Variable |
默认 Default |
描述 Description |
|---|---|---|
|
制作备份文件 make-backup-files |
t t |
如果t,则在首次保存当前文件之前创建当前文件的备份版本。 If t, create a backup version of the current file before saving it for the first time. |
|
复制备份 backup-by-copying |
零 nil |
如果t ,则通过复制而不是 重命名保存到备份版本的文件来创建备份文件 。默认是重命名,这样效率更高。复制可能会产生不同的结果,尤其是当您编辑其他用户拥有的文件时,以及在允许文件“硬链接”(与物理文件关联的备用名称)的操作系统中。有很多变量可以根据上下文调整这种行为;有关详细信息,请查看make-backup-files的在线帮助。 If t, create backup files by copying rather than renaming the file being saved to a backup version. The default is renaming, which is more efficient. Copying can yield different results, especially when you're editing files owned by another user, and in operating systems that allow "hard links" to files (alternate names that are associated with the physical file). There are a raft of variables that can tweak this behavior based on context; check the online help for make-backup-files for the details. |
|
版本控制 version-control |
零 nil |
如果t,则创建文件的编号版本作为备份(名称格式为 filename~N~)。如果nil,则仅对已编号版本的文件执行此操作。如果 ' never(注意前面的单引号),则永远不要制作编号版本。 If t, create numbered versions of files as backups (with names of the form filename~N~). If nil, only do this for files that have numbered versions already. If 'never (note the leading single quote), never make numbered versions. |
|
保留新版本 kept-new-versions |
2 2 |
进行新的编号备份时要保留的文件最新版本的数量。 Number of latest versions of a file to keep when a new numbered backup is made. |
|
保留旧版本 kept-old-versions |
2 2 |
进行新的编号备份时要保留的文件最旧版本的数量。 Number of oldest versions of a file to keep when a new numbered backup is made. |
|
删除旧版本 delete-old-versions |
零 nil |
如果t,则删除多余的版本(不是根据上述变量保留的版本),而不首先要求确认。如果nil,请先请求确认。如果有任何其他值,请勿删除多余的版本。 If t, delete excess versions (not those kept according to the above variables) without asking for confirmation first. If nil, ask for confirmation first. If any other value, don't delete excess versions. |
|
自动保存默认值 auto-save-default |
t t |
如果t,则自动保存访问的每个文件。 If t, do auto-saving of every file visited. |
|
自动保存访问过的文件名 auto-save-visited-file-name |
零 nil |
如果t,则自动保存到正在访问的文件而不是特殊的自动保存文件。 If t, auto-save to the file being visited rather than to a special auto-save file. |
|
自动保存间隔 auto-save-interval |
300 300 |
自动保存之间的击键次数;如果为 0,则关闭自动保存。 Number of keystrokes between auto-saving; if 0, turn off auto-saving. |
|
自动保存超时 auto-save-timeout |
30 30 |
Emacs 自动保存之前的不活动时间长度。如果 为零或0,则关闭此功能。 Length of time of inactivity after which Emacs auto-saves. If nil or 0, turn off this feature. |
|
删除自动保存文件 delete-auto-save-files |
t t |
非零意味着每当保存“真实”文件时就删除自动保存文件。 Non-nil means delete auto-save files whenever the "real" file is saved. |
|
缓冲-提供-保存 buffer-offer-save |
零 nil |
非nil意味着在退出 Emacs 时提议保存当前缓冲区,即使该缓冲区不是文件。 Non-nil means offer to save the current buffer when exiting Emacs, even if the buffer is not a file. |
|
vc 处理后端 vc-handled-backends |
(RCS CVS SVN SCCS Arch MCVS) (RCS CVS SVN SCCS Arch MCVS) |
版本控制系统与vc包一起使用。它们在此列表中出现的顺序控制着在处理新文件时尝试执行它们的顺序。 Version control systems used with the vc package. The order in which they appear in this list controls the order in which they will be attempted when working with a new file. |
|
vc-显示状态 vc-display-status |
t t |
如果非零,则在模式行中显示版本号和锁定状态。 If non-nil, display the version number and the locked state in the mode line. |
|
vc-keep-工作文件 vc-keep-workfiles |
t t |
如果非零,则在向版本控制系统注册更改后不要删除工作文件。 If non-nil, do not delete work files after you register changes with the version control system. |
|
vc-不信任-权限 vc-mistrust-permissions |
零 nil |
如果非零,则不要假设文件的所有者 ID 和权限标志反映了版本控制系统对文件所有权和权限的想法;直接从版本控制系统获取此信息。 If non-nil, do not assume that a file's owner ID and permission flags reflect version control system's idea of file's ownership and permission; get this information directly from version control system. |
|
vc-抑制-确认 vc-suppress-confirm |
零 nil |
如果非零,则在执行版本控制操作之前不要要求确认。 If non-nil, do not ask for confirmation before performing version control actions. |
|
vc-初始注释 vc-initial-comment |
零 nil |
如果非零,则在使用版本控制系统注册文件时提示输入初始注释。 If non-nil, prompt for an initial comment when registering a file with version control system. |
|
vc-make-备份文件 vc-make-backup-files |
零 nil |
如果非零,则对使用版本控制注册的文件进行标准 Emacs 备份。 If non-nil, make standard Emacs backups of files registered with version control. |
|
差速开关 diff-switches |
-C -c |
命令行开关用于控制 VC 和 Command-line switches used to control the format of change reports by
VC as well as |
表 A-2。搜索和替换(第3章)
Table A-2. Searching and replacing (Chapter 3)
|
多变的 Variable |
默认 Default |
描述 Description |
|---|---|---|
|
案例折叠搜索 case-fold-search |
t t |
如果非零,则在搜索时将大小写字母视为相同。 If non-nil, treat upper- and lowercase letters as the same when searching. |
|
大小写替换 case-replace |
t t |
如果非零,则在进行替换时保留字母的原始大小写(即使大小写折叠搜索已打开)。 If non-nil, preserve the original case of letters when doing replaces (even if case-fold-search is on). |
|
搜索大写字母 search-upper-case |
'不猛拉 'not-yanks |
如果非零,则搜索字符串中的大写字母会失败大小写搜索(即强制搜索区分大小写)。符号 ' not-yanks表示将复制文本中的大写字母转换为小写。 If non-nil, uppercase letters in search strings defeat case-fold-search (i.e., force search to be case-sensitive). The symbol 'not-yanks means convert uppercase letters in yanked text to lowercase. |
|
搜索退出选项 search-exit-option |
t t |
如果非零,则除了增量搜索中定义的控制字符(Del、Cj、 Cq、Cr、Cs、 Cw、Cy)之外的任何控制字符都会退出搜索。 If non-nil, any control character other than those defined in incremental search (Del, C-j, C-q, C-r, C-s, C-w, C-y) exits search. |
|
搜索突出显示 search-highlight |
t t |
如果非零,则突出显示部分搜索匹配项。 If non-nil, highlight partial search matches. |
|
查询-替换-突出显示 query-replace-highlight |
t t |
如果非零,则在查询替换模式下突出显示匹配项。 If non-nil, highlight matches in query-replace mode. |
Table A-3. Display (Chapter 2, Chapter 4)
|
多变的 Variable |
默认 Default |
描述 Description |
|---|---|---|
|
下一屏幕上下文行 next-screen-context-lines |
2 2 |
按Cv或Mv向前或向后滚动时保留这么多行 。 Retain this many lines when scrolling forward or backward by C-v or M-v. |
|
滚动步 scroll-step |
0 0 |
将光标垂直移出当前窗口时,向前或向后滚动这么多行。如果为 0,则滚动足够的行以在滚动后将光标置于窗口的中心。 When moving the cursor vertically out of the current window, scroll this many lines forward or backward. If 0, scroll enough lines to place the cursor at the center of the window after scrolling. |
|
水平滚动步 hscroll-step |
0 0 |
将光标水平移出当前窗口时,向左或向右滚动这么多列。如果为 0,则滚动足够的行以在滚动后将光标置于窗口的中心。 When moving the cursor horizontally out of the current window, scroll this many columns left or right. If 0, scroll enough lines to place the cursor at the center of the window after scrolling. |
|
制表符宽度 tab-width |
8 8 |
制表位的宽度;设置后,它成为当前缓冲区的本地缓冲区。 Width of tab stops; when set, it becomes local to the current buffer. |
|
左边距 left-margin |
0 0 |
在基本模式和文本模式下键入Cj时要缩进的列数。 Number of columns to indent when typing C-j in fundamental mode and text mode. |
|
标准缩进 standard-indent |
4 4 |
使用增加或减少边距的命令时缩进的列数。 The number of columns to indent when using commands that increase or decrease margins. |
|
截断行 truncate-lines |
零 nil |
如果非零,则不要换行长行;相反,截断它们并使用箭头来显示该行在屏幕外继续。 (Emacs 的非图形版本使用$来显示线条延伸的位置。) If non-nil, do not wrap long lines; instead, truncate them and use arrows to show that the line continues off-screen. (Nongraphical versions of Emacs use $ instead to show where the line extends.) |
|
截断部分宽度窗口 truncate-partial-width-windows |
t t |
如果非零,则截断所有不是显示器全宽的窗口中的长行(如上所述)。 If non-nil, truncate long lines (as above) in all windows that are not the full width of the display. |
|
窗口最小高度 window-min-height |
4 4 |
窗户的最小允许高度(以行为单位)。 Minimum allowable height of windows (in lines). |
|
窗口最小宽度 window-min-width |
10 10 |
垂直分割窗口的最小允许宽度(以列为单位)。 Minimum allowable width of vertically split windows (in columns). |
|
ctl-箭头 ctl-arrow |
t t |
非零表示使用 ^ X显示控制字符,其中 X是被“控制”的字母。否则,使用八进制(基数 8)ASCII 表示法进行显示 - 例如,Ch在八进制中显示为 \010。 Non-nil means display control characters using ^X, where X is the letter being "controlled." Otherwise, use octal (base 8) ASCII notation for display—for example, C-h appears as \010 in octal. |
|
显示时间-日期-日期 display-time-day-and-date |
零 nil |
如果非零, Mx display-time Enter还将显示日期。 If non-nil, M-x display-time Enter will also show the day and date. |
|
行号模式 line-number-mode |
t t |
如果非零,则在模式行上显示行号。 If non-nil, display the line number on the mode line. |
|
行号显示限制 line-number-display-limit |
零 nil |
应显示行号的缓冲区的最大大小(以字符为单位)。nil值表示没有限制。 Maximum size of buffer (in characters) for which line numbers should be displayed. A value of nil means no limit. |
|
列号模式 column-number-mode |
零 nil |
如果非零,则在模式行上显示列号。 If non-nil, display the column number on the mode line. |
|
可见钟 visible-bell |
零 nil |
如果非零,则在必要时“闪烁”屏幕而不是发出蜂鸣声。 If non-nil, "flash" the screen instead of beeping when necessary. |
|
跟踪-eol track-eol |
零 nil |
如果非零,则每当光标位于行尾时,向上或向下移动光标时“粘”到行尾;否则,停留在光标所在的列中。 If non-nil, whenever the cursor is at the end of the line, "stick" to the end of the line when moving the cursor up or down; otherwise, stay in the column where the cursor is. |
|
闪烁匹配括号 blink-matching-paren |
t t |
如果非零,则在键入相应的右括号时闪烁匹配左括号类型的字符。 If non-nil, blink matching open parenthesis-type character when a corresponding close parenthesis is typed. |
|
眨眼匹配括号距离 blink-matching-paren-distance |
25600 25600 |
键入右括号时,要搜索以查找匹配的左括号字符的最大字符数。 Maximum number of characters to search through to find a matching open parenthesis character when a close parenthesis is typed. |
|
眨眼匹配延迟 blink-matching-delay |
1 1 |
匹配括号闪烁时暂停的秒数。 Number of seconds to pause when blinking a matching parenthesis. |
|
回声击键 echo-keystrokes |
1 1 |
用户暂停这么多秒后,在迷你缓冲区中回显未完成命令的前缀(例如C- ); 0 表示根本不进行回显。 Echo prefixes for unfinished commands (e.g., C-) in minibuffer after user pauses for this many seconds; 0 means don't do echoing at all. |
|
插入默认目录 insert-default-directory |
t t |
如果非零,则在请求文件名时将当前目录插入迷你缓冲区中。 If non-nil, insert the current directory in the minibuffer when asking for a filename. |
|
突出显示非选定窗口 highlight-nonselected-windows |
零 nil |
如果非零,则突出显示当前所选窗口以外的窗口中的区域;适用于 GUI 显示和其他支持突出显示的显示。 If non-nil, highlight regions in windows other than the one currently selected; applies to GUI displays and others that support highlighting. |
|
鼠标滚动延迟 mouse-scroll-delay |
0.25 0.25 |
单击鼠标并将鼠标从窗口内部拖动到窗口边界之外时,屏幕滚动之间的延迟(以秒为单位)。 0 表示尽可能快地滚动。 Delay, in seconds, between screen scrolls when mouse is clicked and dragged from inside a window to beyond its borders. 0 means scroll as fast as possible. |
|
鼠标滚动最小行数 mouse-scroll-min-lines |
1 1 |
单击鼠标并向上或向下拖动到窗口之外时,至少滚动这么多行。 Scroll at least this many lines when mouse is clicked and dragged up or down beyond a window. |
Table A-4. Modes (Chapter 2, Chapter 5, Chapter 7)
|
多变的 Variable |
默认 Default |
描述 Description |
|---|---|---|
|
主模式 major-mode |
基本模式 fundamental-mode |
新缓冲区的默认模式,除非通过文件名设置;设置此变量时,请记住在模式名称前面加上单引号(该值是符号)。 Default mode for new buffers, unless set by virtue of the filename; when setting this variable, remember to precede the mode name with a single quote (the value is a symbol). |
|
默认主模式 default-major-mode |
基本模式 fundamental-mode |
新缓冲区的主要模式。 The major mode for new buffers. |
|
自动模式列表 auto-mode-alist |
(见第10章 ) (see Chapter 10 ) |
文件名和主要模式之间的关联列表。 List of associations between filenames and major modes. |
|
解释者模式主义者 interpreter-mode-alist |
(见第9章 ) (see Chapter 9 ) |
类似于auto-mode-alist 的列表,但适用于 Perl 和 Python 等解释语言。 A list similar to auto-mode-alist, but for interpreted languages like Perl and Python. |
|
缩进制表符模式 indent-tabs-mode |
t t |
如果非零,则在使用Cj缩进时允许使用制表符(以及空格)。这确实会让其他开发人员发疯,因此如果您在团队中工作,您可能应该禁用此功能。 If non-nil, allow the use of tab characters (as well as spaces) when indenting with C-j. This can really drive other developers mad, so you should probably disable this if you are working on a team. |
|
保存版本 dired-kept-versions |
2 2 |
清理 Dired 中的目录时,保留这么多版本的文件。 When cleaning a directory in Dired, keep this many versions of files. |
|
dired-垃圾文件-regexp dired-garbage-files-regexp |
"\\.\\(?:aux\\|bak\\|dvi\\|log\\|orig\\|rej\\|toc\\)\\'" "\\.\\(?:aux\\|bak\\|dvi\\|log\\|orig\\|rej\\|toc\\)\\'" |
定义在 Dired 中选择垃圾文件时标记的文件类型。 Defines what file types are marked when selecting garbage files in Dired. |
|
定向列表开关 dired-listing-switches |
“ -al ” "-al" |
传递给ls命令用于生成直接列表的选项;应至少包含“ -l ”。 Options passed to the ls command for generating dired listings; should contain at least "-l". |
|
直接视图命令列表 dired-view-command-alist |
(见第10章) (see Chapter 10) |
定义 Dired 在打开某些类型的文件时调用的帮助程序应用程序。 Defines helper applications for Dired to invoke when opening certain types of files. |
|
shell 文件名 shell-file-name |
各不相同 varies |
与使用其中之一的函数一起运行的 shell 的文件名,例如 list-directory、dired和compile;取自 Unix 环境变量SHELL的值。 Filename of shell to run with functions that use one, such as list-directory, dired, and compile; taken from value of the Unix environment variable SHELL. |
|
加载路径 load-path |
搜索要加载的 Lisp 包的目录列表(参见第 11 章);通常设置为 系统上 Emacs 源代码安装目录的lisp子目录。 List of directories to search for Lisp packages to load (see Chapter 11); often set to lisp subdirectory of directory where Emacs source code is installed on your system. | |
|
lpr开关 lpr-switches |
零 nil |
定义传递给lpr 的命令行选项 Defines command-line options to pass to lpr |
|
日历周开始日 calendar-week-start-day |
0 0 |
日期定义为一周的第一天。 0 是星期日,1 是星期一,依此类推。 Day defined as first day of the week. 0 is Sunday, 1 is Monday and so on. |
|
图片选项卡字符 picture-tab-characters |
“ !-~ ” "!-~" |
如果字符单独出现在一行上,则它们在图片模式下会被解释为制表位。 Characters interpreted as tab stops in picture mode if they appear on a line of their own. |
Table A-5. Text editing (Chapter 2, Chapter 3, Chapter 7, Chapter 8)
|
多变的 Variable |
默认 Default |
描述 Description |
|---|---|---|
|
句尾 sentence-end |
(见第13章 ) (see Chapter 13 ) |
匹配句子结尾的正则表达式。 Regular expression that matches ends of sentences. |
|
句尾双空格 sentence-end-double-space |
t t |
如果非零,则不要将句号后面的单个空格视为句子结尾。 If non-nil, do not treat single spaces after periods as ends of sentences. |
|
段落分隔 paragraph-separate |
“ [\t\f]*$ ” "[ \t\f]*$" |
匹配分隔段落的行开头的正则表达式。 Regular expression that matches beginnings of lines that separate paragraphs. |
|
段落开头 paragraph-start |
“ \f\\|[ \t]*$ ” "\f\\|[ \t]*$" |
匹配开始或分隔段落的行的开头的正则表达式。 Regular expression that matches beginnings of lines that start or separate paragraphs. |
|
页分隔符 page-delimiter |
“ ^\f ” "^\f" |
匹配分页符的正则表达式。 Regular expression that matches page breaks. |
|
tex-默认模式 tex-default-mode |
'乳胶模式 'latex-mode |
创建文件时调用的模式可以是 TEX 或 LATEX。 Mode to invoke when creating a file that could be either TEX or LATEX. |
|
tex 运行命令 tex-run-command |
“特克斯” "tex" |
用作在模式下文件的子进程中运行的命令的字符串。 Character string used as a command to run in a subprocess on a file in mode. |
|
Latex 运行命令 latex-run-command |
“乳胶” "latex" |
用作在子进程中运行 LATEX 的命令的字符串。 String used as a command to run LATEX in a subprocess. |
|
slimex 运行命令 slitex-run-command |
“狭缝” "slitex" |
用作在子进程中运行 SliTEX 的命令的字符串。 String used as a command to run SliTEX in a subprocess. |
|
tex-dvi-打印命令 tex-dvi-print-command |
“ lpr-d ” "lpr -d" |
用作使用Cc Cp以 tex 模式打印文件的命令的字符串 。 Character string used as a command to print a file in tex mode with C-c C-p. |
|
tex-alt-dvi-打印命令 tex-alt-dvi-print-command |
“ lpr-d ” "lpr -d" |
用于将.dvi文件定向到辅助打印机的命令。 Command to direct .dvi files to a secondary printer. |
|
tex-dvi-查看命令 tex-dvi-view-command |
(if (eq window-system 'x) "xdvi" "dvi2tty * | cat -s") (if (eq window-system 'x) "xdvi" "dvi2tty * | cat -s") |
用作命令的字符串,用于通过Cc Cv查看.dvi 输出文件;该表达式在 X Window 系统上生成xdvi,在其他系统上生成基于终端的替代方案。仅当存在类似 Unix 的操作环境(例如 Mac OS X 或 Windows 下的 Cygwin)时,这才有效。 Character string used as command to view a .dvi output file with C-c C-v; this expression yields xdvi on X Window systems, and a terminal-based alternative on others. This will only work if a Unix-like operating environment is present (such as Mac OS X, or Cygwin under Windows). |
|
tex-报价-保存 tex-offer-save |
t t |
如果非零,则在运行 TEX 之前保存所有未保存的缓冲区。 If non-nil, offer to save any unsaved buffers before running TEX. |
|
tex-show-queue-命令 tex-show-queue-command |
“ lpq ” "lpq" |
用作命令的字符串, 在 Tex 模式下通过Cc Cq显示打印队列。 Character string used as command to show the print queue with C-c C-q in Tex mode. |
|
文本目录 tex-directory |
“ 。 ” "." |
TEX 放置临时文件的目录;默认是当前目录。 Directory for TEX to put temporary files in; default is the current directory. |
|
大纲正则表达式 outline-regexp |
“ [*\f]+ ” "[*\f]+" |
在大纲模式下匹配标题行的正则表达式。 Regular expression that matches heading lines in outline mode. |
|
大纲标题结束正则表达式 outline-heading-end-regexp |
“ \n ” "\n" |
在大纲模式下匹配标题行末尾的正则表达式。 Regular expression that matches ends of heading lines in outline mode. |
|
选择性显示椭圆 selective-display-ellipses |
t t |
如果t,则在大纲模式下显示“...”来代替隐藏文本;否则不显示任何内容。 If t, display "..." in place of hidden text in outline mode; otherwise don't display anything. |
表 A-6。编程(第 9 章)
Table A-6. Programming (Chapter 9)
|
多变的 Variable |
默认 Default |
描述 Description |
|---|---|---|
|
编译命令 compile-command |
“制作-k” "make -k" |
通过 Emacs 语言模式编译文件时使用的默认编译命令。例如,要将 ant 设置为默认编译工具,请将其设置为“ ant -emacs ”。 Default compilation command to use when compiling files via Emacs language modes. For example, to set ant as the default compilation tool, set this to "ant -emacs". |
|
编译错误正则表达式列表 compilation-error-regexp-alist |
(很长的正则表达式) (very long regular expression) |
正则表达式旨在匹配来自 Emacs 支持的所有编译器的错误消息。 Regular expression designed to match error messages from all the compilers supported by Emacs. |
|
评论栏 comment-column |
32 32 |
Emacs 应在其中插入注释的列。如果代码到达此列,则在代码后面插入注释一个空格。 The column at which Emacs should insert comments. If code reaches this column, inserts comment one space beyond code. |
|
多行注释 comment-multi-line |
零 nil |
如果t,则继续注释下一行。如果nil,则在下一行开始新注释。 If t, continue comment on the next line. If nil, start a new comment on the next line. |
|
c 风格列表 c-style-alist |
(见第9章 ) (see Chapter 9 ) |
要使用的代码缩进样式。有很多可用;参见第 9 章。 The code indentation style to use. Many are available; see Chapter 9. |
|
错误调试 debug-on-error |
零 nil |
如果非nil,当评估 Lisp 代码时发生错误时,emacs 将进入调试模式。当您尝试新功能时,这会很方便,但您可能想先阅读调试器的帮助来了解方法。 If non-nil, emacs will go into debug mode when an error occurs in evaluating Lisp code. This can be handy when you're trying out a new function, but you probably want to read the debugger's help first to learn your way around. |
|
c-宏预处理器 c-macro-preprocessor |
“/lib/cpp -C” "/lib/cpp -C" |
定义当您键入Cc Ce时使用哪个命令来调用 C 预处理器 。 Defines which command is used to invoke C preprocessor when you type C-c C-e. |
|
错误时堆栈跟踪 stack-trace-on-error |
零 nil |
如果非nil,Emacs 将在计算 Lisp 代码时发生错误时显示堆栈跟踪。这在与错误调试类似的情况下非常有用 ,并且可以为您提供足够的信息,而无需学习调试器接口。 If non-nil, Emacs displays a stack trace when an error occurs in evaluating Lisp code. This is useful in similar situations as debug-on-error and might give you enough information without having to learn the debugger interface. |
表 A-7。完成(第14章)
Table A-7. Completion (Chapter 14)
|
多变的 Variable |
默认 Default |
描述 Description |
|---|---|---|
|
完成自动帮助 completion-auto-help |
t t |
如果非零,则在补全(通过迷你缓冲区中的Tab或Enter)无效或不明确时提供帮助。 If non-nil, provide help if a completion (via Tab or Enter in minibuffer) is invalid or ambiguous. |
|
完成忽略扩展 completion-ignored-extensions |
(见第14章 ) (see Chapter 14 ) |
完成文件名时 Emacs 会忽略的文件名后缀列表(例如~)。 List of filename suffixes Emacs ignores when completing filenames (for example, ~). |
|
完成-忽略大小写 completion-ignore-case |
零 nil |
如果非零,则在完成时忽略大小写区别。 If non-nil, ignore case distinctions when doing completion. |
表 A-8。各种各样的
Table A-8. Miscellaneous
|
多变的 Variable |
默认 Default |
描述 Description |
|---|---|---|
|
最大杀环 kill-ring-max |
60 60 |
在删除最旧的杀戮之前,将n条已删除的文本保留在杀戮环中。 Keep n pieces of deleted text in the kill ring before deleting oldest kills. |
|
要求最终换行 require-final-newline |
零 nil |
如果保存的文件缺少最后一个换行符:nil表示不添加换行符; t表示自动加一;否则询问是否添加换行符。 If a file being saved is missing a final newline: nil means don't add one; t means add one automatically; otherwise ask whether to add a newline. |
|
下一行添加换行符 next-line-add-newlines |
零 nil |
如果非零,则下一行(Cn或向下箭头)在缓冲区末尾时插入换行符,而不是发出错误信号。 If non-nil, next-line (C-n or down arrow) inserts newlines when at the end of the buffer, rather than signaling an error. |
|
撤消限制、撤消强限制 undo-limit, undo-strong-limit |
20000, 30000 20000, 30000 |
这两个变量共同控制 Emacs 愿意分配多少空间来支持undo 命令。如果您发现自己想要撤消的操作超出了 Emacs 记忆的范围,您可能需要研究增加这些限制;以今天的内存大小来说,它们可能会大得多。 These two variables jointly control how much space Emacs is willing to allocate to supporting the undo command. If you ever find yourself wanting to undo more than past what Emacs remembers, you might want to investigate increasing these limits; with today's memory sizes they can probably comfortably be much larger. |
|
mac 命令键是元 mac-command-key-is-meta |
t t |
如果t,则 Mac Command键用于Meta;如果nil,则Option键为Meta。 If t, the Mac Command key is used for Meta; if nil, the Option key is Meta instead. |
本附录中的表格列出了 Emacs 附带的最有用的 Lisp 包。所有 Lisp 包通常都位于目录 中emacs-source/lisp,其中
emacs-source是放置 Emacs 源发行版的目录。我们省略了所有提供“基本”Emacs 支持的软件包;同样,我们省略了许多包
其功能已经过时或难以言喻的晦涩难懂。
The tables in this appendix list the most useful Lisp packages that
come with Emacs. All Lisp packages are typically located in the
directory emacs-source/lisp, where
emacs-source is the directory in which you
placed the Emacs source distribution. We have omitted all of the
packages that provide "basic" Emacs
support; likewise, we have omitted many packages
whose functionality is obsolete or
unspeakably obscure.
虽然本书中详细描述了其中一些包,但大多数都没有;您必须依靠 GNU Emacs 的帮助才能获得该包功能的精确描述。有关帮助的详细信息,请参阅第 14 章;要了解 Lisp 软件包的功能,您需要的最重要的帮助命令是Ch p(用于finder-by-keyword)、Ch f(用于描述函数)和Ch m(用于描述模式)。
While some of these packages are described in some detail in this book, most aren't; you will have to rely on GNU Emacs' help for precise descriptions of what the package does. See Chapter 14 for details about help; the most important help commands you will need for finding out about the functionality of Lisp packages are C-h p (for finder-by-keyword), C-h f (for describe-function), and C-h m (for describe-mode).
Ch p特别有帮助。它允许您浏览有关系统上可用的所有软件包的信息层次结构,从一般功能区域(如本附录中的表中的功能区域)到有关每个单独模式的Ch m信息。不幸的是,详细信息有时不完整,并且还列出了许多软件包,除了铁杆 Emacs 定制者之外,其他人可能不会感兴趣。
C-h p is especially helpful. It lets you navigate through a hierarchy of information about all packages available on your system, from general areas of functionality, like those in the tables in this appendix, to the C-h m information about each individual mode. Unfortunately, the detailed information is sometimes incomplete and also lists many packages that could not possibly be interesting to anyone other than hard-core Emacs customizers.
只要合理,本附录中的表都会提供“启动”包的命令。该启动信息的含义如下:
Wherever it is reasonable, the tables in this appendix give commands that "start" the package. This startup information has the following meanings:
如果包实现了主要模式,则启动命令是将 Emacs 置于该主要模式的函数。
If the package implements a major mode, the startup command is the function that puts Emacs into this major mode.
如果包实现了当您访问具有特定后缀的文件时自动加载的主要模式,那么
suffixname除了启动命令之外,我们还会列出“后缀”。
If the package implements a major mode that is automatically loaded
when you visit a file with a certain suffix, we list
"suffix
suffixname" in addition
to the startup command.
如果包实现了次要模式,则启动命令是将 Emacs 置于此次要模式的函数。
If the package implements a minor mode, the startup command is the function that puts Emacs into this minor mode.
如果包实现了一组通用函数,我们会尝试选择这些函数中最“典型”的。例如,studly包实现了三个命令。我们任意选择Studlify-region作为调用该包的一种方法。如果没有合理的选择,我们会列出“很多”。
If the package implements a set of general-purpose functions, we've tried to pick the most "typical" of these functions. For example, the studly package implements three commands. We arbitrarily picked studlify-region as one way to invoke this package. If there isn't any reasonable choice, we list "many."
最后,谈谈如何使用这些包。有些包是在 Emacs 启动时自动加载的;有些是在您访问具有适当后缀的文件时加载的(例如编程语言的许多模式);每当您发出适当的命令时,有些就会自动加载(例如,Mx shell Enter加载shell-modeshell.el的包
);有些永远不会自动加载。那么你怎么知道哪个是哪个?
Finally, a word on using the packages. Some packages are
automatically loaded when Emacs starts; some are loaded when you
visit a file with the appropriate suffix (such as many of the modes
for programming languages); some are automatically loaded whenever
you give the appropriate command (for example, M-x shell Enter loads the package
shell.el for shell-mode); and some are never automatically
loaded. So how do you know which is which?
您实际上不必担心这个问题。在表中,“启动”列告诉您哪些命令(或多个命令)使包运行。启动 Emacs,然后输入此命令 ( Mx
Enter )。如果 Emacs 抱怨no match,则该包没有自动加载,您需要“手动”加载该包。要在 Emacs 会话期间执行此操作,请使用命令Mx load-library Enter,其中包的“名称”在表的第一列中给出。您还可以通过在
文件中添加以下形式的行来告诉 Emacs 在启动时自动加载包:startup-command
name
.emacs
You don't really have to concern yourself with this
issue. In the tables, the Startup column tells you what command (or
commands) put the package to work. Start Emacs, and give this command
(M-x
startup-command
Enter). If Emacs complains no match, the package wasn't
loaded automatically and you need to load the package
"by hand." To do so during an Emacs
session, use the command M-x
load-library
name
Enter, where the package's
"name" is given in the first column
of the table. You can also tell Emacs to load packages automatically
at startup time by putting lines in your .emacs
file that have this form:
(加载库“ name”)(load-library "name")最后,如果您有兴趣查看源代码 库,这可能是您在发展 Emacs Lisp 编程技能时学习技术的好方法,请查看第 11 章中介绍的find-library-file函数。
Finally, if you're interested in looking at the source code of the libraries, which can be a great way to pick up techniques as you develop skills in programming Emacs Lisp, check out the find-library-file function presented in Chapter 11.
现在,闲话少说,下面是 Lisp 包的表格。
Now, without further ado, here are the tables of Lisp packages.
表 B-1。支持 Java、C 和 C++ 编程
Table B-1. Support for Java, C, and C++ programming
表 B-2。支持 Lisp 编程
Table B-2. Support for Lisp programming
|
包裹 Package |
描述 Description |
启动 Startup |
|---|---|---|
lisp 模式 lisp-mode |
Lisp、Emacs Lisp 和 Lisp 交互的主要模式 Major modes for Lisp, Emacs Lisp and Lisp interaction |
lisp-mode、 emacs-lisp-mode、 lisp-interaction-mode、后缀
lisp-mode, emacs-lisp-mode, lisp-interaction-mode, suffixes
|
方案 scheme |
编辑Scheme源文件的主要模式 Major mode for editing Scheme source files |
方案模式, 后缀
scheme-mode, suffixes
|
氯 cl |
Emacs Lisp 与 Common Lisp 兼容的函数和宏 Functions and macros for Emacs Lisp compatibility with Common Lisp |
许多 many |
调试 debug |
调试 Emacs Lisp 程序的主要模式 Major mode for debugging Emacs Lisp programs |
debug ,如果debug-on-error不为nil时运行代码发生错误,则自动调用 debug, automatically invoked if an error occurs running code when debug-on-error is not nil |
错误 edebug |
Emacs Lisp 调试功能,作为次要模式实现 Emacs Lisp debugging functionality, implemented as a minor mode |
错误 edebug |
驳斥 disass |
反汇编已编译的 Emacs Lisp 代码的函数 Function to disassemble compiled Emacs Lisp code |
拆卸 disassemble |
埃尔普 elp |
Emacs Lisp 的代码分析器 Code profiler for Emacs Lisp |
elp 仪器包, elp 仪器功能 elp-instrument-package, elp-instrument-function |
痕迹 trace |
为 Emacs Lisp 生成函数调用跟踪 Produces function call traces for Emacs Lisp |
跟踪函数 trace-function |
表 B-3。支持其他编程任务和语言
Table B-3. Support for other programming tasks and languages
表 B-4。支持文本处理
Table B-4. Support for Text Processing
|
包裹 Package |
描述 Description |
启动 Startup |
|---|---|---|
文本模式 text-mode |
编辑未处理的文本文件的主要模式 Major mode for editing unprocessed text files |
文本模式、后缀
text-mode, suffixes
|
sgml模式 sgml-mode |
编辑结构化文档(包括HTML和XML)的主要模式[ 2 ] Major mode for editing structured documents (including HTML and XML)[2] |
html-模式, xml-模式, sgml-模式, 后缀
html-mode, xml-mode, sgml-mode, suffixes |
文本模式 tex-mode |
编辑 TEX 和 LATEX 文件的主要模式 Major mode for editing TEX and LATEX files |
tex-mode , Latex-mode ,后缀
tex-mode, latex-mode, suffixes
|
比布克斯 bibtex |
编辑参考书目文件的主要模式 Major mode for editing bibliography files |
bibtex模式,后缀
bibtex-mode, suffix
|
参考书目 refbib |
将refer 格式的参考书目文件转换为bibtex格式 Convert bibliography files in refer format to bibtex format |
r2b 转换缓冲区 r2b-convert-buffer |
诺夫 nroff |
编辑nroff和 troff文本文件的主要模式 Major mode for editing nroff and troff text files |
nroff-mode、后缀
nroff-mode, suffixes
|
隶 scribe |
编辑 Scribe 文本文件的主要模式 Major mode for editing Scribe text files |
抄写模式,后缀
scribe-mode, suffix
|
表 B-6。操作系统实用程序的接口[ 3 ]
Table B-6. Interfaces to operating system utilities[3]
|
包裹 Package |
描述 Description |
启动 Startup |
|---|---|---|
壳 shell |
与命令行 shell 交互的主要模式。 Major mode for interacting with the command-line shell. |
shell模式 shell-mode |
查找目录 find-dired |
运行find命令并 在生成的文件列表上使用dired 。 Run the find command and use dired on the resulting list of files. |
查找目录 find-dired |
tar 模式 tar-mode |
通过类似于dired 的界面访问tar存档内的文件。 Access files inside a tar archive through a dired-like interface. |
tar 模式, 后缀
tar-mode, suffix
|
弧形模式 arc-mode |
通过类似于dired的界面访问其他几种存档格式的文件。 Access files in several other archive formats through a dired-like interface. |
存档模式、后缀
archive-mode, suffixes
|
LPR lpr |
打印缓冲区或区域的内容。 Print the contents of a buffer or region. |
lpr 缓冲区,打印缓冲区, lpr 区域,打印区域 lpr-buffer, print-buffer, lpr-region, print-region |
种类 sort |
对缓冲区的内容进行排序。 Sort the contents of a buffer. |
排序列、排序字段、排序行、排序数字字段、排序段落、排序正则表达式字段 sort-columns, sort-fields, sort-lines, sort-numeric-fields, sort-paragraphs, sort-regexp-fields |
拼写,拼写 spell, ispell |
用于检查拼写的各种工具。 Various tools for checking spelling. |
参见第 3 章 See Chapter 3 |
差异,差异 diff, ediff |
帮助比较文件的工具。 Tools to help in comparing files. |
参见第 12 章 See Chapter 12 |
[ 3 ]仅当您安装了像 Cygwin 这样的 Unix 兼容包(参见http://www.cygwin.com)时,其中一些才在 Windows 上有用。 [3] Some of these will be useful on Windows only if you've installed a Unix compatibility package like Cygwin (see http://www.cygwin.com). | ||
表 B-7。网络支持
Table B-7. Networking support
表 B-8。游戏和娱乐
Table B-8. Games and amusements
再次强调,这只是一些可用软件包的示例,旨在让您了解 Emacs 附带的功能的广度和深度。即使就目前可用的功能而言,该列表也尚未接近完整,而且总是会添加新功能。您最好的选择是使用本附录开头提到的工具自行探索。并且不要忘记在 Web 上搜索非标准添加内容,这些添加内容可能正是您自己的环境和项目所需要的!
Again, this is only a sampling of some available packages, to give you a sense of the breadth and depth of capabilities that ship with Emacs. The list isn't close to complete even with respect to what's available at this time, and new features are always being added. Your best bet is to explore for yourself using the tools mentioned at the beginning of this appendix. And don't forget to search the Web for nonstandard additions that might be just what you need for your own environment and projects!
没有完美的程序。 GNU Emacs 经过非常彻底的调试,但肯定有可能发现无法正常工作的东西。
There are no perfect programs. GNU Emacs is very thoroughly debugged, but it is certainly possible to find things that don't work correctly.
自由软件基金会 (FSF) 欢迎问题报告。然而,它们必须是真正的问题 报告;关于某件事应该如何工作的简单意见分歧不是错误。如果您认为某个命令应该以不同的方式工作,请记住 Emacs 已经存在很长时间并且拥有许多用户;无法更改它来满足单个用户。 (另一方面,在大多数情况下,您可以自己编写一些 Lisp 来更改它。)在 GNU Emacs 手册中,FSF 发布了一些报告错误的优秀指南,我们将很快对其进行总结:
The Free Software Foundation (FSF) welcomes problem reports. However, they need to be real problem reports; simple differences of opinion about how something should work are not bugs. If you think that a certain command should work differently, remember that Emacs has been around for a long time and has many users; it can't be changed to satisfy a single user. (On the other hand, in most cases, you could write some Lisp to change it yourself.) In the GNU Emacs Manual, the FSF publishes some excellent guidelines for reporting bugs, which we'll summarize very quickly:
在报告错误之前,请查看它是否在已知问题列表中。您可以通过输入Ch Ce查看此列表。
Before you report a bug, see if it's on the list of known problems. You can view this list by typing C-h C-e.
如果您遇到某种系统错误(Emacs 转储核心、因分段错误而终止、崩溃、挂起或执行其他反社会操作),那么您肯定遇到了错误。
You most certainly have a bug if you run into some kind of system error (Emacs dumps core, terminates with a segmentation fault, crashes, hangs, or does something else antisocial).
报告错误时,请尽可能具体。一些命令将帮助您准确报告出现问题时发生的情况。 Ch l(用于view-lossage)报告您最近进行的 100 次左右的按键操作;Mx open-dribble-file filename将您键入的每个击键保存在指定的filename中。
When reporting bugs, be as specific as possible. A few commands will help you report exactly what was happening when things went awry. C-h l (for view-lossage) reports the last 100 or so keystrokes you made; M-x open-dribble-file filename saves every keystroke you type in the specified filename.
FSF 不鼓励您尝试解释错误报告中的错误。 “我做了这样那样的事,结果发生了”是有用的,特别是如果问题是可重复的; “我认为字体处理存在问题”根本没有提供任何有用的信息。
The FSF discourages you from trying to interpret bugs in the bug report. "I did thus-and-such and this happened" is useful, particularly if the problem is repeatable; "I think there's a problem with font handling" doesn't give any useful information at all.
始终报告您正在使用的 Emacs 版本。命令 Mx emacs-version为您提供相关信息。
Always report which version of Emacs you are using. The command M-x emacs-version gives you the relevant information.
始终报告您正在编辑的文件的内容(如果有影响)、. emacs文件的内容、您所处的模式以及您必须加载才能创建的任何 Lisp 库(自定义或其他)问题。
Always report the contents of the file you were editing (if it makes a difference), the contents of your .emacs file, which mode you were in, and any Lisp libraries (custom or otherwise) that you have to load in order to create the problem.
我们将添加一项非常重要的准则:
We will add one very important guideline:
尽管我们已尽一切努力写一本准确的书,但我们还远未达到完美。考虑到这一点,请不要在报告错误时引用本书作为权威。尽管我们没有提出要求,但自由软件基金会完全有理由拒绝任何基于第三方出版物的错误报告。如果您怀疑存在错误,请使用 GNU Emacs 手册或帮助工具来找出给您带来麻烦的命令的真正用途。在这样做的过程中,你可能会发现这本书是不正确的;如果您这样做,请将问题报告给 booktech@oreilly.com。
Although we have taken every effort to write a book that is accurate, we are far from perfect. With that in mind, please do not cite this book as an authority when reporting a bug. Although we haven't asked, the Free Software Foundation would be completely justified in rejecting any bug reports based on a third-party publication. If you suspect a bug, use the GNU Emacs Manual or the help facility to find out what the command that's giving you trouble is really supposed to do. In doing so, you may find out that this book is incorrect; if you do, please report the problem to booktech@oreilly.com.
如果您确实需要报告错误,请输入Mx report-emacs-bug从 Emacs 内发送。系统将提示您输入主题行并进入 Emacs 发送邮件的界面。如果来自 Emacs 的邮件设置不正确,您可以 使用您首选的邮件客户端向emacs-pretest-bug@gnu.org发送电子邮件。请务必包含总结问题的信息丰富的主题行。
If you do have a bug to report, type M-x report-emacs-bug to send it from within Emacs. You'll be prompted for a subject line and dropped into Emacs' interface for sending mail. If mail from Emacs isn't set up properly, you can email emacs-pretest-bug@gnu.org using your preferred mail client. Be sure to include an informative subject line that summarizes the problem.
本附录包括一些有用的 Emacs 网站。其中列出的一些描述了 Emacs 的附加包。在某些情况下,这些网站多年来一直保持稳定,并且很可能保持这种状态。在其他情况下,网站会不断变化,URL 也会发生变化。如果您发现此列表中有错误或有添加建议,请发送电子邮件至booktech@oreilly.com。
This appendix includes some helpful Emacs web sites. Some of those listed describe add-on packages for Emacs. In some cases, the sites have been stable for years and are likely to remain that way. In other cases, web sites come and go and URLs change. If you find errors in this list or have suggestions for additions, please email us at booktech@oreilly.com.
表 D-1。 Emacs 网站
Table D-1. Emacs web sites
|
网站 Web site |
网址 URL |
|---|---|
|
自由软件基金会 The Free Software Foundation | |
|
GNU Emacs 的官方网站 The official web site for GNU Emacs | |
|
GNU 通用公共许可证 The GNU General Public License | |
|
本书的网站 The web site for this book | |
|
非常非官方的 dotemacs 主页( .emacs文件的大量集合,可帮助您创建自己的文件) The very unofficial dotemacs home (great collection of .emacs files to aid you in creating your own) | |
|
Dotfiles.com(包括其他应用程序以及 Emacs 的点文件) Dotfiles.com (includes dot files for other applications as well as Emacs) | |
|
Emacs 维基 The Emacs Wiki | |
|
Emacs 俳句 Emacs Haiku | |
|
Emacs 实现 Emacs implementations | |
|
David Wheeler 的文章主张为开源项目提供兼容 GPL 的许可证 David Wheeler's essay arguing for a GPL-compatible license for open source projects |
表 D-2。平台和可访问性相关网站
Table D-2. Platform and accessibility-related web sites
|
网站 Web site |
网址 URL |
|---|---|
|
FSF 的 Emacs for Unix 和 Windows 下载站点 FSF's download site for Emacs for Unix and Windows | |
|
Andrew Choi 的 Mac OS X 常见问题解答和构建说明 Andrew Choi's Mac OS X FAQ and build instructions |
http://members.shaw.ca/akochoi-emacs/ http://members.shaw.ca/akochoi-emacs/ http://members.shaw.ca/akochoi-emacs/stories/obtaining-andbuilding.html http://members.shaw.ca/akochoi-emacs/stories/obtaining-andbuilding.html |
|
Alex Rice 的 Mac OS X 版本 Alex Rice's Mac OS X build | |
|
Fink,Mac OS X 的 Unix 软件安装程序 Fink, a Unix software installer for Mac OS X | |
|
John Schneider 的“让 Mac OS X.3 的行为几乎就像我的 Linux 机器一样” John Schneider's "Getting Mac OS X.3 toBehave Almost Like My Linux Boxes" | |
|
Nqmacs,Windows Emacs 二进制文件 Nqmacs, a Windows Emacs binary | |
|
Cygwin:适用于 Windows 的 Unix 命令 Cygwin: Unix commands for Windows | |
|
Ngai Kim Hoong 的有关 Emacs 和 Cygwin 的页面(甚至 Emacs 和 Palm Pilots) Ngai Kim Hoong's page relating to Emacs and Cygwin (even Emacs and Palm Pilots) | |
|
Kim Storm 的 CUA 模式 Kim Storm's CUA mode | |
|
Emacspeak(Emacs 的音频接口) Emacspeak (an audio interface to Emacs) |
表 D-3。与文本相关的网站
Table D-3. Text-related sites
|
网站 Web site |
网址 URL |
|---|---|
|
伊斯佩尔常见问题解答 Ispell FAQ | |
|
Raymond Zeitler 的帖子指出了适用于 Windows 的 Ispell 的正确版本 Raymond Zeitler's post pointing to the right version of Ispell for Windows |
http://lists.nongnu.org/archive/html/help-emacs-windows/2004-06/msg00023.html http://lists.nongnu.org/archive/html/help-emacs-windows/2004-06/msg00023.html |
|
Eric Pement 的“理解 GNU Emacs 和 Tabs”页面 Eric Pement's "Understanding GNU Emacs and Tabs" page | |
|
Eric Pement 的 awk 脚本,用于将大纲模式大纲转换为经典大纲格式 Eric Pement's awk scripts for converting to outline mode outlines to classical outline formats |
http://www.student.northpark.edu/pemente/awk/outline_classic11.awk.txt http://www.student.northpark.edu/pemente/awk/outline_classic11.awk.txt http://www.student.northpark.edu/pemente/awk/outline_numbered11.awk.txt http://www.student.northpark.edu/pemente/awk/outline_numbered11.awk.txt |
|
ASCII 艺术(图片模式的乐趣) ASCII art (fun with picture mode) |
表 D-4。编程语言、版本控制和定制站点
Table D-4. Programming languages, version control, and customization sites
|
网站 Web site |
网址 URL |
|---|---|
|
CPAN(综合 Perl 档案网络) CPAN (the Comprehensive Perl Archive Network) | |
|
Emacs 开发环境工具集合 (CEDET) Collection of Emacs Development Environment Tools (CEDET) | |
|
JDEE网站 JDEE site | |
|
PHP模式 PHP mode | |
|
颠覆 Subversion | |
|
Clearcase 扩展( Clearcase extensions ( |
表 D-5。标记语言相关网站
Table D-5. Markup language-related sites
|
网站 Web site |
网址 URL |
|---|---|
|
psgml模式 psgml mode | |
|
来自 OpenACS 的 psgml 设置说明 psgml setup instructions from OpenACS | |
|
Norm Walsh 的 DocBook 网站 Norm Walsh's DocBook site | |
|
TEI Emacs(还包括适用于 Linux 和 Windows 的 JDEE) TEI Emacs (also includes JDEE for Linux and Windows) | |
|
Jim Clark 的 nxml 模式 Jim Clark's nxml mode | |
|
Nxml 模式邮件列表 Nxml mode mailing list | |
|
放松NG RELAX NG | |
|
HTML 帮助模式 HTML helper mode | |
|
HTML模式豪华 HTMLModeDeluxe | |
|
Darren Brierton 的 Emacs WebDev 环境 Darren Brierton's Emacs WebDev Environment |
本快速参考按主题排列,其顺序与文本中处理命令的顺序大致相同。不幸的是,不可能既“快速”又彻底,尤其是对于像 GNU Emacs 这样庞大而全面的编辑器。我们试图在完整性和快速性之间走一条中间道路;我们承认,如果我们犯了错误,我们就犯了急于求成的错误。
This quick reference is arranged topically, in roughly the same order as the commands were treated in the text. Unfortunately, it's impossible to be both "quick" and thorough, particularly with an editor as large and comprehensive as GNU Emacs. We've tried to take a middle road between completeness and quickness; we'll confess that, if we've erred, we've erred on the side of quickness.
表 E-1。文件处理命令(第一章)
Table E-1. File-handling commands (Chapter 1)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
Cx Cf 文件 → 打开文件 C-x C-f File → Open File |
查找文件 find-file |
找到文件并在新缓冲区中读取它。 Find file and read it in a new buffer. |
|
CXCv C-x C-v |
查找备用文件 find-alternate-file |
读取备用文件,用Cx Cf替换读取的文件。 Read an alternate file, replacing the one read with C-x C-f. |
|
Cx i 文件 → 插入文件 C-x i File → Insert File |
插入文件 insert-file |
在光标位置插入文件。 Insert file at cursor position. |
|
Cx Cs 文件 → 保存(当前缓冲区) C-x C-s File → Save (current buffer) |
保存缓冲区 save-buffer |
保存存档。 Save file. |
|
Cx Cw 文件 → 将缓冲区另存为 C-x C-w File → Save Buffer As |
写文件 write-file |
将缓冲区内容写入文件。 Write buffer contents to file. |
|
Cx Cc 文件 → 退出 Emacs C-x C-c File → Exit Emacs |
保存缓冲区-杀死-emacs save-buffers-kill-emacs |
退出 Emacs。 Exit Emacs. |
表 E-2。光标移动命令(第二章)
Table E-2. Cursor movement commands (Chapter 2)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CF C-f |
转发字符 forward-char |
向前移动一个字符(右)。 Move forward one character (right). |
|
镉 C-b |
向后字符 backward-char |
向后移动一个字符(左)。 Move backward one character (left). |
|
CP C-p |
上一行 previous-line |
移至上一行(向上)。 Move to previous line (up). |
|
中文 C-n |
下一行 next-line |
移至下一行(向下)。 Move to next line (down). |
|
MF M-f |
前向字 forward-word |
向前移动一个字。 Move one word forward. |
|
MB M-b |
后向词 backward-word |
向后移动一个字。 Move one word backward. |
|
钙 C-a |
行首 beginning-of-line |
移至行首。 Move to beginning of line. |
|
铈 C-e |
行结束 end-of-line |
移至行尾。 Move to end of line. |
|
我 M-e |
前句 forward-sentence |
向前推进一句话。 Move forward one sentence. |
|
嘛 M-a |
向后句 backward-sentence |
向后移动一句话。 Move backward one sentence. |
|
简历 C-v |
向上滑动 scroll-up |
向前移动一屏。 Move forward one screen. |
|
MV M-v |
向下滚动 scroll-down |
向后移动一屏。 Move backward one screen. |
|
M-< M-< |
缓冲区开始 beginning-of-buffer |
移至文件开头。 Move to beginning of file. |
|
中号-> M-> |
缓冲区结束 end-of-buffer |
移至文件末尾。 Move to end of file. |
|
(没有任何) (none) |
转到行 goto-line |
转到文件的第n行。 Go to line n of file. |
|
(没有任何) (none) |
转到字符 goto-char |
转到文件的第n 个字符。 Go to character n of file. |
|
M- n M- n |
数字参数 digit-argument |
重复下一个命令n次。 Repeat the next command n times. |
|
铜 C-u n |
普遍论证 universal-argument |
重复下一个命令n次(如果省略n则重复四次)。 Repeat the next command n times (four times if you omit n). |
表 E-3。删除、拉动、区域和剪贴板命令(第 2 章)
Table E-3. Deleting, yanking, region, and clipboard commands(Chapter 2)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
光盘 C-d |
删除字符 delete-char |
删除光标下的字符。 Delete character under cursor. |
|
德尔 Del |
删除向后字符 delete-backward-char |
删除前一个字符。 Delete previous character. |
|
MD M-d |
杀戮词 kill-word |
删除下一个单词。 Delete next word. |
|
M-德尔 M-Del |
向后杀字 backward-kill-word |
删除前一个单词。 Delete previous word. |
|
Cy 编辑 → 粘贴最近的内容 C-y Edit → Paste Most Recent |
猛拉 yank |
恢复您删除的内容。 Restore what you've deleted. |
|
Cw 编辑 → 剪切 C-w Edit → Cut |
杀伤区 kill-region |
删除标记的区域(请参阅下一节)。 Delete a marked region (see next section). |
|
C-@ 或 C- 空格 C-@ or C- Space |
设置标记命令 set-mark-command |
标记区域的开始(或结束)。 Mark the beginning (or end) of a region. |
|
CX CX C-x C-x |
交换点和标记 exchange-point-and-mark |
交换光标和标记的位置。 Exchange location of cursor and mark. |
|
连续波 C-w |
杀伤区 kill-region |
删除区域。 Delete the region. |
|
CY C-y |
猛拉 yank |
粘贴最近删除或复制的文本。 Paste most recently killed or copied text. |
|
分子量 M-w |
杀环保存 kill-ring-save |
复制该区域(以便可以使用Cy进行粘贴)。 Copy the region (so it can be pasted with C-y). |
|
CXh C-x h |
标记整个缓冲区 mark-whole-buffer |
标记缓冲区。 Mark buffer. |
|
我的 M-y |
猛拉流行音乐 yank-pop |
Cy之后,粘贴之前的删除内容。 After C-y, pastes earlier deletion. |
|
(没有任何) (none) |
剪贴板终止区域 clipboard-kill-region |
剪切区域并将其放置在杀伤环和系统剪贴板上。 Cut region and place both in kill ring and on system clipboard. |
|
(没有任何) (none) |
剪贴板复制 clipboard-yank |
从剪贴板粘贴文本。 Paste text from clipboard. |
|
(没有任何) (none) |
剪贴板-杀死-环-保存 clipboard-kill-ring-save |
将文本复制到剪贴板。 Copy text to clipboard. |
表 E-4。文本填充和重新格式化命令(第 2 章)
Table E-4. Text filling and reformatting commands (Chapter 2)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
(无)选项 → 文本模式下的自动换行 (none) Options → Word Wrap in Text Modes |
自动填充模式 auto-fill-mode |
切换自动填充模式,在该模式下,Emacs 在您键入段落时格式化它们。 Toggle auto-fill mode, in which Emacs formats paragraphs as you type them. |
|
米q M-q |
填充段落 fill-paragraph |
重新格式化段落。 Reformat paragraph. |
|
(无)编辑 → 填充 (none) Edit → Fill |
填充区域 fill-region |
重新格式化区域内的各个段落。 Reformat individual paragraphs within a region. |
表 E-5。停止和撤消命令(第 2 章)
Table E-5. Stopping and undoing commands (Chapter 2)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
钙 C-g |
键盘退出 keyboard-quit |
中止当前命令。 Abort current command. |
|
CXu C-x u |
广告撤消 advertised-undo |
撤消上次编辑(可以重复完成)。 Undo last edit (can be done repeatedly). |
|
C-_ 编辑 → 撤消 C-_ Edit → Undo |
撤消 undo |
撤消上次编辑。 Undo last edit. |
|
(没有任何) (none) |
恢复缓冲区 revert-buffer |
将缓冲区恢复到文件上次保存(或自动保存)时的状态。 Restore buffer to the state it was in when the file was last saved (or auto-saved). |
表 E-6。搜索和替换命令(第 3 章)
Table E-6. Search and replace commands (Chapter 3)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
Cs 编辑 → 搜索 → 增量搜索 → 转发字符串 C-s Edit → Search → Incremental Search → Forward String |
isearch-forward isearch-forward |
开始向前增量搜索;接下来是搜索字符串。另外,查找搜索字符串的下一个出现(向前)。 Start incremental search forward; follow by search string. Also, find next occurrence (forward) of search string. |
|
Cr 编辑 → 搜索 → 增量搜索 → 向后字符串 C-r Edit → Search → Incremental Search → Backward String |
isearch-向后 isearch-backward |
开始向后增量搜索;接下来是搜索字符串。另外,查找搜索字符串的下一个出现(向后)。 Start incremental search backward; follow by search string. Also, find next occurrence (backward) of search string. |
表 E-7。正则表达式搜索命令(第3章)
Table E-7. Regular expression search commands (Chapter 3)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CM 输入 编辑 → 搜索 → 正则表达式转发 C-M-s Enter Edit → Search → Regexp Forward |
研究向前 re-search-forward |
向前搜索正则表达式。 Search for a regular expression forward. |
|
CMr 输入 编辑 → 搜索 → 正则表达式向后 C-M-r Enter Edit → Search → Regexp Backwards |
向后研究 re-search-backward |
向后搜索正则表达式。 Search for a regular expression backward. |
|
CM 编辑 → 搜索 → 增量搜索 → 正向正则表达式 C-M-s Edit → Search → Incremental Search → Forward Regexp |
isearch-forward-正则表达式 isearch-forward-regexp |
逐步向前搜索正则表达式。 Search incrementally forward for a regular expression. |
|
CMR 编辑 → 搜索 → 增量搜索 → 向后正则表达式 C-M-r Edit → Search → Incremental Search → Backward Regexp |
isearch-向后-正则表达式 isearch-backward-regexp |
向后增量搜索正则表达式。 Search incrementally backward for a regular expression. |
|
CM-% 编辑 → 替换 → 替换正则表达式 C-M-% Edit → Replace → Replace Regexp |
查询替换正则表达式 query-replace-regexp |
查询-替换正则表达式。 Query-replace a regular expression. |
表 E-8。拼写检查命令(第 3 章)
Table E-8. Spell-checking commands (Chapter 3)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
(无)工具 → 拼写检查 → 拼写检查缓冲区 (none) Tools → Spell Checking → Spell-Check Buffer |
ispell 缓冲区 ispell-buffer |
检查缓冲区的拼写。 Check spelling of the buffer. |
|
(无)工具 → 拼写检查 → 拼写检查注释 (none) Tools → Spell Checking → Spell-Check Comments |
ispell 注释和字符串 ispell-comments-and-strings |
检查程序中注释和字符串的拼写。 Checks spelling of comments and strings in a program. |
|
(无) 工具 → 拼写检查 → 自动拼写检查 (Flyspell) (none) Tools → Spell Checking → Automatic Spell-Checking (Flyspell) |
飞行咒语模式 flyspell-mode |
进入 Flyspell 小模式,其中拼写错误的单词会突出显示。 Enter the flyspell minor mode, in which incorrectly spelled words are highlighted. |
|
(没有任何) (none) |
Flyspell缓冲区 flyspell-buffer |
对当前缓冲区进行拼写检查,为所有拼写错误的单词添加下划线。使用鼠标中键进行更正。 Spell-check the current buffer, underlining all misspelled words. Use middle mouse button to correct. |
表 E-9。缓冲区命令(第 4 章)
Table E-9. Buffer commands (Chapter 4)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
Cx b 缓冲区 → 选择命名缓冲区 C-x b Buffers → Select Named Buffer |
切换到缓冲区 switch-to-buffer |
移动到指定的缓冲区。 Move to the buffer specified. |
|
Cx → 缓冲区 → 下一个缓冲区 C-x → Buffers → Next Buffer |
下一个缓冲区 next-buffer |
移动到缓冲区列表中的下一个缓冲区。 Move to the next buffer in the buffer list. |
|
Cx 缓冲区 → 上一个缓冲区 C-x Buffers → Previous Buffer |
前一个缓冲区 previous-buffer |
移动到缓冲区列表中的上一个缓冲区。 Move to the previous buffer in the buffer list. |
|
Cx Cb 缓冲区 → 列出所有缓冲区 C-x C-b Buffers → List All Buffers |
列表缓冲区 list-buffers |
显示缓冲区列表。 Display the buffer list. |
|
CXk C-x k |
终止缓冲区 kill-buffer |
删除指定的缓冲区。 Delete the buffer specified. |
|
(没有任何) (none) |
杀死一些缓冲区 kill-some-buffers |
询问删除每个缓冲区。 Ask about deleting each buffer. |
表 E-10。窗户和框架(第四章)
Table E-10. Windows and frames (Chapter 4)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
Cx 2 文件 → 分割窗口 C-x 2 File → Split Window |
垂直分割窗口 split-window-vertically |
将当前窗口分成两个窗口,一个在另一个窗口之上。 Divide current window into two windows, one above the other. |
|
CX 3 C-x 3 |
水平分割窗口 split-window-horizontally |
将当前窗口分成两个并排的窗口。 Divide current window into two side-by-side windows. |
|
CXO C-x o |
其他窗口 other-window |
移至另一个窗口;如果有多个,则移至下一个窗口。 Move to the other window; if there are several, move to the next window. |
|
CX 0 C-x 0 |
删除窗口 delete-window |
删除当前窗口。 Delete the current window. |
|
Cx 1 文件 → 未分割的窗口 C-x 1 File → Unsplit Windows |
删除其他窗口 delete-other-windows |
删除除此窗口之外的所有窗口。 Delete all windows but this one. |
|
CX 4 f C-x 4 f |
查找文件其他窗口 find-file-other-window |
在另一个窗口中查找文件。 Find a file in the other window. |
|
CX 4 b C-x 4 b |
切换到缓冲区其他窗口 switch-to-buffer-other-window |
在另一个窗口中选择一个缓冲区。 Select a buffer in the other window. |
|
(无)工具 → 比较 (Ediff) → 本窗口和下一个窗口 (none) Tools → Compare (Ediff) → This Window and Next Window |
比较窗口 compare-windows |
将此窗口与下一个窗口进行比较并显示第一个差异。 Compare this window with the next window and show the first difference. |
|
Cx 5 o 缓冲区 → 帧 C-x 5 o Buffers → Frames |
其他框架 other-frame |
移至其他框架。 Move to other frame. |
|
Cx 5 0 文件 → 删除帧 C-x 5 0 File → Delete Frame |
删除帧 delete-frame |
删除当前帧。 Delete current frame. |
|
Cx 5 2 文件 → 新框架 C-x 5 2 File → New Frame |
制作框架 make-frame |
在当前缓冲区上创建一个新帧。 Create a new frame on the current buffer. |
|
CX 5 f C-x 5 f |
查找文件其他框架 find-file-other-frame |
在新框架中查找文件。 Find file in a new frame. |
|
CX 5 r C-x 5 r |
查找文件只读其他框架 find-file-read-only-other-frame |
在新框架中查找文件,但该文件是只读的。 Finds a file in a new frame, but it is read-only. |
|
CX 5 b C-x 5 b |
切换到缓冲区其他帧 switch-to-buffer-other-frame |
制作框架并在其中显示其他缓冲区。 Make frame and display other buffer in it. |
表 E-11。 Shell模式命令(第5章)
Table E-11. Shell mode commands (Chapter 5)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
(没有任何) (none) |
壳 shell |
进入外壳模式。 Enter shell mode. |
|
抄送抄送 信号 → BREAK C-c C-c Signals → BREAK |
comint 中断子作业 comint-interrupt-subjob |
中断当前工作;相当于抄送。 Interrupt current job; equivalent to C-c. |
|
抄送 Cz 信号 → 停止 C-c C-z Signals → STOP |
comint-停止-子作业 comint-stop-subjob |
暂停或停止工作;Unix shell 中的Cz 。 Suspend or stop a job; C-z in Unix shells. |
|
Mp 输入/输出 → 上一个输入 M-p In/Out → Previous Input |
comint-前一个输入 comint-previous-input |
检索以前的命令(可以重复查找以前的命令)。 Retrieve previous commands (can be repeated to find earlier commands). |
|
Mn 输入/输出 → 下一个输入 M-n In/Out → Next Input |
comint 下一个输入 comint-next-input |
检索后续命令(可以重复以查找更多最近的命令)。 Retrieve subsequent commands (can be repeated to find more recent commands). |
|
进入 Enter |
comint-发送-输入 comint-send-input |
在当前行发送输入。 Send input on current line. |
|
标签 Tab |
comint 动态完成 comint-dynamic-complete |
完成当前命令、文件名或变量名。 Complete current command, filename, or variable name. |
表 E-12。定向命令(第 5 章)
Table E-12. Dired commands (Chapter 5)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
Cx d 文件 → 打开目录 C-x d File → Open Directory |
迪雷德 dired |
开始 Dired。 Start Dired. |
|
C 操作 → 复制到 C Operate → Copy to |
直接复制 dired-do-copy |
复制文件。 Copy file. |
|
d 标记 → 旗帜 d Mark → Flag |
dired 标志文件删除 dired-flag-file-deletion |
标记为删除。 Flag for deletion. |
|
D 操作 → 删除 D Operate → Delete |
直接删除 dired-do-delete |
查询立即删除。 Query for immediate deletion. |
|
F f |
dired-广告查找文件 dired-advertised-find-file |
查找(以便您可以编辑)。 Find (so you can edit). |
|
g 立即 → 刷新 g Immediate → Refresh |
恢复缓冲区 revert-buffer |
从磁盘重新读取目录。 Reread the directory from disk. |
|
m或* m 标记 → 标记 m or * m Mark → Mark |
迪雷德标记 dired-mark |
用*标记。 Mark with *. |
|
Q 操作 → 文件中查询替换 Q Operate → Query Replace in Files |
直接执行查询替换 dired-do-query-replace |
查询标记文件中的替换字符串。 Query replace string in marked files. |
|
R 操作 → 重命名为 R Operate → Rename to |
直接重命名 dired-do-rename |
重新命名文件。 Rename file. |
|
s s |
直接排序切换或编辑 dired-sort-toggle-or-edit |
按日期或按文件名对 Dired 显示进行排序(在这两者之间切换)。 Sort the Dired display by date or by filename (toggles between these). |
|
t 标记 → 切换标记 t Mark → Toggle Marks |
直接切换标记 dired-toggle-marks |
切换文件和目录上的标记;按一次t标记所有未标记的文件和目录;再次按t可恢复原始标记。 Toggle marks on files and directories; pressing t once marks all unmarked files and directories; pressing t again restores original marks. |
|
u 标记 → 取消标记 u Mark → Unmark |
取消标记 dired-unmark |
去除标记。 Remove mark. |
|
+ 立即 → 创建目录 + Immediate → Create Directory |
dired 创建目录 dired-create-directory |
创建一个目录。 Create a directory. |
|
*!或M-Del Mark → 全部取消标记 * ! or M-Del Mark → Unmark All |
dired-取消标记所有文件 dired-unmark-all-files |
删除所有文件中的所有标记。 Remove all marks from all files. |
表 E-13。宏命令(第六章)
Table E-13. Macro commands (Chapter 6)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CX ( C-x ( |
kmacro-开始宏 kmacro-start-macro |
开始宏定义。 Start macro definition. |
|
F3 F3 |
kmacro-启动宏-或插入-计数器 kmacro-start-macro-or-insert-counter |
开始宏定义。如果在定义宏时按下,则插入一个计数器。 Start macro definition. If pressed while defining a macro, insert a counter. |
|
CX) C-x ) |
kmacro 结束宏 kmacro-end-macro |
结束宏定义。 End macro definition. |
|
F4 F4 |
kmacro 结束或调用宏 kmacro-end-or-call-macro |
结束宏定义(如果定义正在进行中)或调用最后一个键盘宏。 End macro definition (if definition is in progress) or invoke last keyboard macro. |
|
CXe C-x e |
kmacro 结束和调用宏 kmacro-end-and-call-macro |
执行最后定义的键盘宏。可以输入e来重复宏。 Execute last keyboard macro defined. Can type e to repeat macro. |
|
CXCn C-x C-k n |
名称姓氏 kbd 宏 name-last-kbd-macro |
命名您最后创建的宏(保存之前)。 Name the last macro you created (before saving it). |
|
CXCe C-x C-k e |
编辑 kbd 宏 edit-kbd-macro |
通过键入 Cx e(代表最后定义的键盘宏)、Mx(代表命名宏)、Ch l(代表丢失)或击键(代表绑定到某个键的宏)来编辑键盘宏。 Edit a keyboard macro by typing C-x e for the last keyboard macro defined, M-x for a named macro, C-h l for lossage, or keystrokes for a macro bound to a key. |
|
Cx Ck 输入 C-x C-k Enter |
kmacro-编辑宏 kmacro-edit-macro |
编辑最后一个键盘宏。 Edit the last keyboard macro. |
表 E-14。大纲模式命令(第7章)
Table E-14. Outline mode commands (Chapter 7)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
(没有任何) (none) |
轮廓模式 outline-mode |
切换轮廓模式 Toggle outline mode |
|
抄送抄送隐藏 → 隐藏正文 C-c C-t Hide → Hide Body |
隐藏体 hide-body |
隐藏所有身体线条。 Hide all body lines. |
|
Cc Ca显示 → 显示全部 C-c C-a Show → Show All |
显示所有 show-all |
显示隐藏的一切。 Show everything that's hidden. |
表 E-15。编译模式命令(第9章)
Table E-15. Compilation mode commands (Chapter 9)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CX` C-x ` |
下一个错误 next-error |
转到下一条错误消息并访问相应的源代码。 Move to the next error message and visit the corresponding source code. |
|
锰 M-n |
编译下一个错误 compilation-next-error |
移至下一条错误消息。 Move to the next error message. |
|
熔点 M-p |
编译前一个错误 compilation-previous-error |
移至上一条错误消息。 Move to the previous error message. |
|
抄送抄送 C-c C-c |
编译转到错误 compilation-goto-error |
访问当前错误消息的源代码。 Visit the source code for the current error message. |
Table E-16. Basic indentation commands (Chapter 7 and Chapter 9)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
厘米-\ C-M-\ |
缩进区域 indent-region |
缩进光标和标记之间的每一行。 Indent each line between the cursor and mark. |
|
毫米 M-m |
回到缩进 back-to-indentation |
移至该行的第一个非空白字符。 Move to the first nonblank character on the line. |
|
M-^ M-^ |
删除缩进 delete-indentation |
将此行连接到上一行。 Join this line to the previous one. |
表 E-17。 C运动命令(第9章)
Table E-17. C motion commands (Chapter 9)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
嘛 M-a |
c-语句开头 c-beginning-of-statement |
移至当前语句的开头。 Move to the beginning of the current statement. |
|
我 M-e |
c-语句结束 c-end-of-statement |
移至当前语句的末尾。 Move to the end of the current statement. |
|
米q M-q |
c-填充段落 c-fill-paragraph |
如果在评论中,请填写该段落,保留缩进和修饰。 If in comment, fill the paragraph, preserving indentations and decorations. |
|
CM C-M-a |
开始的乐趣 beginning-of-defun |
移至该点周围函数体的开头。 Move to the beginning of the body of the function surrounding the point. |
|
CM C-M-e |
结束乐趣 end-of-defun |
移至函数末尾。 Move to the end of the function. |
|
CMh C-M-h |
c 标记功能 c-mark-function |
将光标置于函数的开头,将标记置于函数的结尾。 Put the cursor at the beginning of the function, the mark at the end. |
|
抄送Cq C-c C-q |
c-缩进-defun c-indent-defun |
根据缩进样式缩进整个函数。 Indent the entire function according to indentation style. |
|
铜铜 C-c C-u |
c-up-条件式 c-up-conditional |
移至当前预处理器条件的开头。 Move to the beginning of the current preprocessor conditional. |
|
抄送 Cp C-c C-p |
c-后向条件 c-backward-conditional |
移至上一个预处理器条件。 Move to the previous preprocessor conditional. |
|
抄送中国 C-c C-n |
c-前向条件 c-forward-conditional |
移至下一个预处理器条件。 Move to the next preprocessor conditional. |
表 E-18。 SQL模式命令(第9章)
Table E-18. SQL mode commands (Chapter 9)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
抄送抄送 C-c C-c |
sql 发送段落 sql-send-paragraph |
发送光标所在的段落。段落由特定的数据库客户端定义。例如,对于sql-mysql进程,一个段落以 select 或 update 等语句开头,并以分号结尾。任意数量的线路都可以介入。 Send the paragraph the cursor is on. A paragraph is defined by the particular database client. For the sql-mysql process, for example, a paragraph begins with a statement like select or update and ends with a semicolon. Any number of lines can intervene. |
|
CC铬 C-c C-r |
sql 发送区域 sql-send-region |
发送标记的区域。 Send the marked region. |
|
抄送 抄送 C-c C-b |
sql 发送缓冲区 sql-send-buffer |
发送整个缓冲区。 Send the entire buffer. |
表 E-19。 Lisp 命令(第 9 章)
Table E-19. Lisp commands (Chapter 9)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CMb C-M-b |
后向性别 backward-sexp |
向后移动一个 S 表达式。 Move backward by one S-expression. |
|
CMf C-M-f |
前向性别 forward-sexp |
向前移动一个 S 表达式。 Move forward by one S-expression. |
|
CMt C-M-t |
转置性别 transpose-sexps |
调换光标周围的两个 S 表达式。 Transpose the two S-expressions around the cursor. |
|
厘米-@ C-M-@ |
标记性别 mark-sexp |
将标记设置为当前 S 表达式的末尾;将光标设置到开头。 Set mark to the end of the current S-expression; set the cursor to the beginning. |
|
CMk C-M-k |
杀戮性爱 kill-sexp |
删除光标后面的 S 表达式。 Delete the S-expression following the cursor. |
|
(没有任何) (none) |
向后杀性 backward-kill-sexp |
删除光标前面的 S 表达式。 Delete the S-expression preceding the cursor. |
|
锰 C-M-n |
转发列表 forward-list |
向前移动一个列表。 Move forward by one list. |
|
CMp C-M-p |
向后列表 backward-list |
向后移动一个列表。 Move backward by one list. |
|
CMd C-M-d |
下列表 down-list |
向前和向下移动一级括号。 Move forward and down one parenthesis level. |
|
(没有任何) (none) |
上行列表 up-list |
向前移出一个括号级别。 Move forward out of one parenthesis level. |
|
CMu C-M-u |
向后向上列表 backward-up-list |
向后移出一个括号级别。 Move backward out of one parenthesis level. |
|
CM C-M-a |
开始的乐趣 beginning-of-defun |
移至当前函数的开头。 Move to the beginning of the current function. |
|
CM C-M-e |
结束乐趣 end-of-defun |
移至当前函数的末尾。 Move to the end of the current function. |
|
CMh C-M-h |
马克德芬 mark-defun |
将光标置于函数开头,将标记置于函数末尾。 Put the cursor at the beginning of the function, put the mark at the end. |
表 E-20。 VC命令(第12章)
Table E-20. VC commands (Chapter 12)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
CXVV C-x v v |
vc 下一个操作 vc-next-action |
转到下一个逻辑版本控制状态。 Go to the next logical version control state. |
|
CXVD C-x v d |
vc目录 vc-directory |
显示目录下的所有已注册文件。 Show all registered files beneath a directory. |
|
Cx v = C-x v = |
vc-差异 vc-diff |
生成版本差异报告。 Generate a version difference report. |
|
CX 视觉 C-x v u |
vc 恢复缓冲区 vc-revert-buffer |
丢弃自上次签入修订版以来的更改。 Throw away changes since the last checked-in revision. |
|
CX v ~ C-x v ~ |
vc 版本其他窗口 vc-version-other-window |
在另一个窗口中检索给定的修订版本。 Retrieve a given revision in another window. |
|
CXVl C-x v l |
vc打印日志 vc-print-log |
显示文件的更改注释和历史记录。 Display a file's change comments and history. |
|
CX六 C-x v i |
vc-寄存器 vc-register |
注册文件以进行版本控制。 Register a file for version control. |
|
CXVH C-x v h |
vc 插入标头 vc-insert-headers |
在文件中插入版本控制标头。 Insert version control headers in a file. |
|
CXVR C-x v r |
vc-检索快照 vc-retrieve-snapshot |
查看指定的项目快照。 Check out a named project snapshot. |
|
CX 与 C-x v s |
vc-创建快照 vc-create-snapshot |
创建命名项目快照。 Create a named project snapshot. |
|
CXVC C-x v c |
vc 取消版本 vc-cancel-version |
丢弃已保存的修订版本。 Throw away a saved revision. |
|
CXVA C-x v a |
vc 更新更改日志 vc-update-change-log |
更新 GNU 风格的 ChangeLog 文件。 Update a GNU-style ChangeLog file. |
表 E-21。 Ediff命令(第12章)
Table E-21. Ediff commands (Chapter 12)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
空格或n Space or n |
ediff-下一个差异 ediff-next-difference |
移至文件之间的下一个差异。 Move to the next difference between the files. |
|
德尔或p Del or p |
ediff-前一个差异 ediff-previous-difference |
移至文件之间的先前差异。 Move to the preceding difference between the files. |
|
j j |
ediff 跳转到差异 ediff-jump-to-difference |
转到指定为数字前缀参数的差值。 Go to the difference specified as a numeric prefix argument. |
|
A a |
ediff-复制 A 到 B ediff-copy-A-to-B |
将缓冲区 A 中找到的当前差异的版本复制到缓冲区 B。 Copy the version of the current difference found in buffer A to buffer B. |
|
乙 b |
ediff 复制 B 到 A ediff-copy-B-to-A |
将缓冲区 B 中找到的当前差异的版本复制到缓冲区 A。 Copy the version of the current difference found in buffer B to buffer A. |
|
ra或rb r a or r b |
ediff-恢复-差异 ediff-restore-diff |
将缓冲区 A(或 B)中的当前差异恢复到从其他缓冲区复制之前的状态。 Restore the current difference in buffer A (or B) to the way it was before copying from the other buffer. |
|
甲或乙 A or B |
ediff 切换只读 ediff-toggle-read-only |
将指定的缓冲区切换为(或退出)只读模式。 Switch the specified buffer into (or out of) read-only mode. |
|
ga或g b g a or g b |
ediff 跳转到点差异 ediff-jump-to-difference-at-point |
将比较缓冲区重新放置在指定缓冲区中最接近当前位置(点)的差异上。 Recenter the comparison buffers on the difference nearest to your current location (point) in the specified buffer. |
|
! ! |
ediff-更新-差异 ediff-update-diffs |
重新计算并重新显示突出显示的区域;如果您手动对缓冲区进行了大量更改,则非常有用。 Recalculate and redisplay the highlighted regions; useful if you've manually made extensive changes to a buffer. |
|
wa或w b w a or w b |
ediff 保存缓冲区 ediff-save-buffer |
将指定的缓冲区保存到磁盘。 Save the specified buffer to disk. |
|
z z |
ediff-暂停 ediff-suspend |
关闭 Ediff 控制窗口,但使会话保持活动状态,以便稍后恢复。 Close the Ediff control window, but leave the session active so you can resume it later. |
|
q q |
ediff-退出 ediff-quit |
关闭 Ediff 窗口并结束本次比较会话。 Close the Ediff window and end this comparison session. |
表 E-22。 CUA模式命令(第13章)
Table E-22. CUA mode commands (Chapter 13)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
抄送 CX CX C-c C-x C-x |
cua 交换点和标记 cua-exchange-point-and-mark |
交换光标和标记的位置。 Exchange location of cursor and mark. |
|
Cx 或 C-w 或 S-删除 C-x or C-w or S-Delete |
杀伤区 kill-region |
删除区域。 Delete the region. |
|
Cv 或 C-y 或 S-插入 C-v or C-y or S-Insert |
铜浆糊 cua-paste |
粘贴最近删除或复制的文本。 Paste most recently killed or copied text. |
|
抄送 C-c |
复制区域作为终止 copy-region-as-kill |
复制区域。 Copy the region. |
|
MV M-v |
cua 重复替换区域 cua-repeat-replace-region |
突出显示并替换一个字符串后,找到下一个字符串并以相同的方式替换它。 After highlighting and replacing a string, find the next string and replace it the same way. |
|
我的 M-y |
cua-paste-pop cua-paste-pop |
在Cv之后,粘贴先前删除的内容。 After C-v, pastes earlier deletion. |
|
Cz 或 C-x u C-z or C-x u |
取消撤销 cua-undo |
撤消最后一次更改。 Undoes the last change. |
|
CxCz C-x C-z |
图标化框架 iconify-frame |
最小化当前帧(Cz 在 CUA 模式之外执行的操作)。 Minimize the current frame (what C-z does outside CUA mode). |
表 E-23。帮助命令(第14章)
Table E-23. Help commands (Chapter 14)
|
击键 Keystrokes |
命令名称 Command name |
问题已回答 Question answered |
|---|---|---|
|
Ch k 帮助 → 描述 → 描述键 C-h k Help → Describe → Describe Key |
描述键 describe-key |
这个击键序列运行什么命令,它有什么作用? What command does this keystroke sequence run, and what does it do? |
|
Ch f 帮助 → 描述 → 描述功能 C-h f Help → Describe → Describe Function |
描述功能 describe-function |
这个函数有什么作用? What does this function do? |
|
Ch v 帮助 → 描述 → 描述变量 C-h v Help → Describe → Describe Variable |
描述变量 describe-variable |
这个变量是什么意思,它的值是多少? What does this variable mean, and what is its value? |
|
Ch m 帮助 → 描述 → 描述缓冲模式 C-h m Help → Describe → Describe Buffer Modes |
描述模式 describe-mode |
告诉我当前缓冲区所处的模式。 Tell me about the modes the current buffer is in. |
|
Ch b 帮助 → 描述 → 列出按键绑定 C-h b Help → Describe → List Key Bindings |
描述绑定 describe-bindings |
该缓冲区的所有键绑定是什么? What are all the key bindings for this buffer? |
|
查 帮助 → 搜索文档 → 按名称查找命令 C-h a Help → Search Documentation → Find Commands by Name |
apropos 命令 apropos-command |
哪些命令包含这个词? What commands include this word? |
|
(无) 帮助 → 搜索文档 → 按名称查找选项 (none) Help → Search Documentation → Find Options by Name |
apropos 变量 apropos-variable |
哪些变量包含此正则表达式? What variables include this regular expression? |
|
(无) 帮助 → 搜索文档 → 按名称查找任何对象 (none) Help → Search Documentation → Find Any Object by Name |
恰到好处 apropos |
该正则表达式涉及哪些函数和变量? What functions and variables involve this regular expression? |
表 E-24。文档帮助命令(第14章)
Table E-24. Documentation help commands (Chapter 14)
|
击键 Keystrokes |
命令名称 Command name |
行动 Action |
|---|---|---|
|
Ch t 帮助 → Emacs 教程 C-h t Help → Emacs Tutorial |
教程帮助 help-with-tutorial |
运行 Emacs 教程。 Run the Emacs tutorial. |
|
气 C-h i |
信息 info |
启动信息文档阅读器。如果以Cu开头,则读取您选择的信息文件。 Start the Info documentation reader. If prefaced with C-u, reads an Info file of your choice. |
|
Ch r 帮助 → 阅读 Emacs 手册 C-h r Help → Read the Emacs Manual |
信息 emacs 手册 info-emacs-manual |
打开 Emacs 手册。 Open the Emacs manual. |
|
Ch K 帮助 → 更多手册 → 在手册中查找密钥 C-h K Help → More Manuals → Find Key in Manual |
信息-goto-emacs-key-command-node Info-goto-emacs-key-command-node |
在讨论此键序列的节点启动信息文档阅读器。 Start Info documentation reader at the node that discusses this key sequence. |
|
(无) 帮助 → 搜索文档 → 在用户手册中查找主题 (none) Help → Search Documentation → Look Up Subject in User Manual |
emacs-索引-搜索 emacs-index-search |
搜索 Emacs 用户手册的索引。 Search the index of the Emacs user manual. |
|
CHp C-h p |
按关键字查找 finder-by-keyword |
调用一个菜单,让您获取有关系统上可用的 Emacs Lisp 软件包的信息。 Invoke a menu that lets you get information about Emacs Lisp packages available on your system. |
表 E-25。重要模式
Table E-25. Important modes
|
模式 Mode |
功能 Function |
|---|---|
|
基本模式 fundamental-mode |
默认模式 The default mode |
|
文本模式 text-mode |
文本写作的主要模式(第二章) Major mode for writing text (Chapter 2) |
|
轮廓模式 outline-mode |
写大纲的主要模式(第七章) Major mode for writing outlines (Chapter 7) |
|
图片模式 picture-mode |
使用键盘创建 ASCII 绘图的主要模式(第 7 章) Major mode for creating ASCII drawings using the keyboard (Chapter 7) |
|
html模式 html-mode |
编写 HTML 的主要模式(第 8 章) Major mode for writing HTML (Chapter 8) |
|
sgml模式 sgml-mode |
编写SGML和XML的主要模式(第8章) Major mode for writing SGML and XML (Chapter 8) |
|
乳胶模式 latex-mode |
TEX 和 LATEX 格式化文件的主要模式(第 8 章) Major mode for formatting files for TEX and LATEX (Chapter 8) |
|
c 模式、c++ 模式 c-mode, c++-mode |
编写C、C++、Java程序的主要模式(第9章) Major mode for writing C and C++, and Java programs (Chapter 9) |
|
java模式 java-mode |
编写Java程序的主要模式(第9章) Major mode for writing Java programs (Chapter 9) |
|
perl 模式, cperl 模式 perl-mode, cperl-mode |
编写Perl程序的主要模式(第9章) Major modes for writing Perl programs (Chapter 9) |
|
SQL模式 sql-mode |
使用SQL与数据库交互的主要模式(第9章) Major mode for interacting with databases using SQL (Chapter 9) |
|
emacs-lisp-模式 emacs-lisp-mode |
编写 Emacs Lisp 函数的主要模式(第 9 章和第11 章) Major mode for writing Emacs Lisp functions (Chapter 9 and Chapter 11) |
|
lisp 模式 lisp-mode |
Major mode for writing Lisp programs (Chapter 9 and Chapter 11) |
|
Lisp 交互模式 lisp-interaction-mode |
编写和评估 Lisp 表达式的主要模式( 第 9 章和第 11章) Major mode for writing and evaluating Lisp expressions ( Chapter 9 andChapter 11) |
|
自动填充模式 auto-fill-mode |
启用自动换行的次要模式(第 2 章) Minor mode that enables word wrap (Chapter 2) |
|
覆盖模式 overwrite-mode |
次要模式,在您键入时替换字符而不是插入字符(第 2 章) Minor mode that replaces characters as you type instead of inserting them (Chapter 2) |
|
飞行咒语模式 flyspell-mode |
Flyspell 拼写检查器的次要模式(第 3 章) Minor mode for flyspell spell-checker (Chapter 3) |
|
Flyspell-prog-模式 flyspell-prog-mode |
使用 Flyspell 进行拼写检查程序的次要模式(第 3 章) Minor mode for spell-checking programs with flyspell (Chapter 3) |
|
缩写模式 abbrev-mode |
单词缩写的小模式(第3章) Minor mode for word abbreviations (Chapter 3) |
|
艺术家模式 artist-mode |
使用鼠标创建 ASCII 绘图的次要模式(第 7 章) Minor mode for creating ASCII drawings using the mouse (Chapter 7) |
|
字体锁定模式 font-lock-mode |
用于突出显示颜色和字体文本的次要模式(第 9 章) Minor mode for highlighting text in colors and fonts (Chapter 9) |
|
vc模式 vc-mode |
使用版本控制系统的次要模式(第12章) Minor mode for using version control systems (Chapter 12) |
我们的外观是读者评论、我们自己的实验以及发行渠道反馈的结果。独特的封面补充了我们处理技术主题的独特方法,为潜在的枯燥主题注入个性和生命力。
Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.
《学习 GNU Emacs,第三版》封面上的动物是 gnu(或牛羚)。牛羚是栖息在塞伦盖蒂平原的非洲羚羊。雄性牛羚(公牛)身高可达 52 英寸,体重可达 500 磅,并拥有所有羚羊中最致命的角。公牛的领地意识很强,往往独来独往。雌性和幼体通常生活在小群中。然而,它们在迁徙过程中可能会聚集数以万计。牛羚是狮子最喜欢的猎物。
The animal on the cover of Learning GNU Emacs, Third Edition is a gnu (or wildebeest). Gnus are African antelopes that inhabit the Serengeti Plains. Male gnus (bulls) reach up to 52 inches in height and 500 pounds inweight, and have the most lethal horns of any of the antelopes. Bulls are very territorial and tend to remain alone. The females and young generally live in small herds. However, they may congregate in the tens of thousands during migration. Gnus are the favorite prey of lions.
Jamie Peppard 是 Learning GNU Emacs Third Edition 的制作编辑和校对者。南希·莱因哈特 (Nancy Reinhardt) 是文案编辑。 Adam Witwer 和 Claire Cloutier 负责质量控制。玛丽·阿格纳提供了制作协助。约翰娜·范胡斯·丁斯 (Johnna VanHoose Dinse) 撰写了该索引。
Jamie Peppard was the production editor and proofreader for Learning GNU Emacs Third Edition. Nancy Reinhardt was the copyeditor . Adam Witwer and Claire Cloutier provided quality control. Mary Agner provided production assistance. Johnna VanHoose Dinse wrote the index.
埃迪·弗里德曼 (Edie Freedman) 使用多佛图画档案馆中的 19 世纪版画设计了这本书的封面。 Clay Fernald 使用 Quark Express 4.1 使用 Adobe 的 ITC Garamond 字体制作了封面布局。 Emma Colby 使用 Adobe InDesign CS 使用 Linotype Birka 和 Adobe Myriad Condensed 字体制作了快速参考卡。
Edie Freedman designed the cover of this book using a 19th-century engraving from the Dover Pictorial Archive. Clay Fernald produced the cover layout with Quark Express 4.1 using Adobe's ITC Garamond font. Emma Colby produced the Quick Reference card with Adobe InDesign CS using the fonts Linotype Birka and Adobe Myriad Condensed.
Melanie Wang 根据 David Futato 的系列设计设计了室内布局。 Julie Hawks 使用 Erik Ray、Jason McIntosh、Neil Walls 和 Mike Sierra 创建的使用 Perl 和 XML 技术的格式转换工具将本书转换为 FrameMaker 5.5.6。文字字体为Linotype Birka;标题字体为 Adobe Myriad Condensed;代码字体是 LucasFont 的 TheSans Mono Condensed。书中出现的插图由 Robert Romano 和 Jessamyn Read 使用 Macromedia FreeHand MX 和 Adobe Photoshop CS 制作。
Melanie Wang designed the interior layout, based on a series design by David Futato. This book was converted by Julie Hawks to FrameMaker 5.5.6 with a format conversion tool created by Erik Ray, Jason McIntosh, Neil Walls, and Mike Sierra that uses Perl and XML technologies. The text font is Linotype Birka; the heading font is Adobe Myriad Condensed; and the code font is LucasFont's TheSans Mono Condensed. The illustrations that appear in the book were produced by Robert Romano and Jessamyn Read using Macromedia FreeHand MX and Adobe Photoshop CS.
本书的在线版本是由 Safari 制作组(John Chodacki、Ken Douglass 和 Ellie Cutler)创建的,使用了一组由 Erik Ray、Benn Salter、John Chodacki 编写和维护的 Frame-to-XML 转换和清理工具,艾莉·卡特勒和杰夫·利格特。
The online edition of this book was created by the Safari production group (John Chodacki, Ken Douglass, and Ellie Cutler) using a set of Frame-to-XML conversion and cleanup tools written and maintained by Erik Ray, Benn Salter, John Chodacki, Ellie Cutler, and Jeff Liggett.